PGSQL之开窗函数PARTITION BY

偶然间让DB帮忙写一个SQL,直接感受是:这也太方便太酷了吧!!!!

所谓的[SQL写得好的人,非常受欢迎],一万个同意!!

最近碰到一个需求,大概就是这个意思

一个人可以重复录入多条数据,昨天一条,今天一条,今天即为有效,昨天为无效
如果是同一天录入,则按照创建时间先后判定有无效

想到了如下几种原始方式:

最笨的方式 先按时间倒序查列表,然后使用代码来进行逻辑判断,再进行数据的封装

最好的方式 所有逻辑判断和代码都由SQL(一个函数!)替代

方式1-逻辑判断

列表已经查出来,当时也很笨的进行了逻辑判断,对于我这种逻辑混乱的人来说,头疼

各种if,然后各种bug、数据错乱等问题,疯了

然后问了下隔壁的DB,丢给我一个函数

方式2-SQL处理

OVER(PARTITION BY)函数
开窗函数,Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值
它和聚合函数的不同之处是:对于每个组返回多行,而聚合函数对于每个组只返回一行
开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化

搭配ROW_NUMBER() OVER ()使用效果绝佳!

1
2
3
4
5
6
SELECT ROW_NUMBER
() OVER ( PARTITION BY rybh ORDER BY jdrq DESC, crt_time DESC ) bj,
jdrq,
crt_time
FROM
table

红框处,按照人员编号进行分组,并且按照登记日期和创建时间进行降序

那么相同人员的数据,第一条永远是最新的!

那么bj=1即为有效,否则无效,就是这么厉害!解决了多少行代码!!!


完整SQL:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
WITH cs AS (
SELECT ROW_NUMBER
() OVER ( PARTITION BY b.rybh ORDER BY b.jdrq DESC, b.crt_time DESC ) bj,
b.ID,
b.rybh,
f_b_getryxm ( b.rybh ) AS xm,
f_b_formatdatestr ( b.jdrq, 'yyyy-mm-dd' ) AS jdrq,
b.crt_time
FROM
t_d_k_wsgl_bgqzcs b
LEFT JOIN t_d_ryxx r ON b.rybh = r.rybh
) SELECT ROW_NUMBER
() OVER ( ORDER BY jdrq DESC, crt_time DESC ) rn,
ID,
rybh,
xm,
jdrq,
crt_time,
CASE
bj
WHEN 1 THEN
'有效' ELSE'无效'
END sfyx
FROM
cs
-- WHERE bj = 1

------本文结束感谢阅读------

本文标题:PGSQL之开窗函数PARTITION BY

文章作者:churuo

原始链接:https://www.xuchuruo.cn/用Sql替代复杂的逻辑代码.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

0%