需要 Oracle SQL 中的日期增量数
Need to number of Date increments in Oracle SQL
需要 Oracle 中日期递增的次数 SQL
create table zzenp_so_multi_rs
(
so_number varchar2(30),
rev_number number,
line_number number,
rs_date date,
status varchar2(30)
)
;
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 1, 1, '15-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 2, 1, '16-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 3, 1, '16-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 4, 1, '14-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 5, 1, '14-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 6, 1, '17-MAY-2022', 'Open');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10001', 1, 1, '17-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10001', 2, 1, '15-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10001', 3, 1, '12-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10001', 4, 1, '16-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10001', 5, 1, '13-MAY-2022', 'Open');
在这里,我们有销售订单号、修订号、行号、RS 日期和状态。每修改一行,插入一条记录,状态修改为引用旧记录&打开新记录。
我需要 no_of_push_outs 的计算函数/子查询。这仅适用于日期被推出(日期递增)而不是被拉入的时间。
SELECT SO_NUMBER, REV_NUMBER, LINE_NUMBER, RS_DATE, <> no_of_push_outs
FROM zzenp_so_multi_rs
WHERE status = 'Open'
我是这样理解的
temp
CTE 计算之前的rs_date
,然后用它来求和push-outs(因为你不能有解析sum
聚合中的函数)。
SQL> WITH
2 temp
3 AS
4 (SELECT so_number,
5 rev_number,
6 line_number,
7 rs_date,
8 status,
9 LAG (rs_date) OVER (PARTITION BY so_number ORDER BY rev_number) prev_rs_date
10 FROM zzenp_so_multi_rs)
11 SELECT z.so_number,
12 z.line_number,
13 (SELECT MAX (b.rev_number)
14 FROM zzenp_so_multi_rs b
15 WHERE b.so_number = z.so_number
16 AND b.status = 'Open') rev_number,
17 (SELECT MAX (b.rs_date)
18 FROM zzenp_so_multi_rs b
19 WHERE b.so_number = z.so_number
20 AND b.status = 'Open') rs_date,
21 SUM (CASE WHEN z.rs_date > z.prev_rs_date THEN 1 ELSE 0 END) l_sum
22 FROM temp z
23 GROUP BY z.so_number, z.line_number
24 ORDER BY z.so_number;
SO_NUMBER LINE_NUMBER REV_NUMBER RS_DATE L_SUM
------------------------------ ----------- ---------- ---------- ----------
10000 1 6 17.05.2022 2
10001 1 5 13.05.2022 1
SQL>
对于 Oracle 12.1 及更高版本,您可以使用 match_recognize
来获得干净、优雅的解决方案。
select so_number, rev_number, line_number, rs_date, no_of_push_outs
from zzenp_so_multi_rs
match_recognize (
partition by so_number, line_number
order by rev_number
measures last(rev_number) as rev_number,
count(up.*) as no_of_push_outs,
last(rs_date) as rs_date
pattern ( (up|other)* )
define up as rs_date > prev(rs_date)
);
还使用 LAG()
获取日期数量增加,但希望更简单的加入
with pout as (
select so_number, count(*) no_of_push_outs from (
select z.so_number, rs_date,
lag(rs_date) over (partition by so_number order by rev_number) p_rs_date
from zzenp_so_multi_rs z
)
where rs_date > p_rs_date
group by so_number
)
select z.*, pout.no_of_push_outs
from zzenp_so_multi_rs z, pout
where z.so_number=pout.so_number
and z.status='Open';
您可以使用 LAG
和 COUNT
分析函数(没有任何 self-joins):
SELECT *
FROM (
SELECT so_number,
rev_number,
line_number,
rs_date,
status,
COUNT(is_push_out) OVER (PARTITION BY so_number) AS no_of_push_outs
FROM (
SELECT z.*,
CASE
WHEN LAG(rs_date) OVER (PARTITION BY so_number ORDER BY rev_number)
< rs_date
THEN 1
END AS is_push_out
FROM zzenp_so_multi_rs z
)
)
WHERE status = 'Open';
或者,您可以使用 LAG
分析函数,然后使用 GROUP BY
和 KEEP (DENSE_RANK LAST ORDER BY rev_number)
获取聚合函数中最后修订的数据:
SELECT so_number,
MAX(rev_number) AS rev_number,
MAX(line_number) KEEP (DENSE_RANK LAST ORDER BY rev_number)
AS line_number,
MAX(rs_date) KEEP (DENSE_RANK LAST ORDER BY rev_number)
AS rs_date,
MAX(status) KEEP (DENSE_RANK LAST ORDER BY rev_number)
AS status,
COUNT(is_push_out) AS no_of_push_outs
FROM (
SELECT z.*,
CASE
WHEN LAG(rs_date) OVER (PARTITION BY so_number ORDER BY rev_number)
< rs_date
THEN 1
END AS is_push_out
FROM zzenp_so_multi_rs z
)
GROUP BY so_number;
其中,对于示例数据,都输出:
SO_NUMBER
REV_NUMBER
LINE_NUMBER
RS_DATE
STATUS
NO_OF_PUSH_OUTS
10000
6
1
17-MAY-22
Open
2
10001
5
1
13-MAY-22
Open
1
db<>fiddle here
需要 Oracle 中日期递增的次数 SQL
create table zzenp_so_multi_rs
(
so_number varchar2(30),
rev_number number,
line_number number,
rs_date date,
status varchar2(30)
)
;
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 1, 1, '15-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 2, 1, '16-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 3, 1, '16-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 4, 1, '14-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 5, 1, '14-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10000', 6, 1, '17-MAY-2022', 'Open');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10001', 1, 1, '17-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10001', 2, 1, '15-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10001', 3, 1, '12-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10001', 4, 1, '16-MAY-2022', 'Reference');
insert into zzenp_so_multi_rs (so_number,rev_number,line_number, rs_date, status ) values ('10001', 5, 1, '13-MAY-2022', 'Open');
在这里,我们有销售订单号、修订号、行号、RS 日期和状态。每修改一行,插入一条记录,状态修改为引用旧记录&打开新记录。
我需要 no_of_push_outs 的计算函数/子查询。这仅适用于日期被推出(日期递增)而不是被拉入的时间。
SELECT SO_NUMBER, REV_NUMBER, LINE_NUMBER, RS_DATE, <> no_of_push_outs
FROM zzenp_so_multi_rs
WHERE status = 'Open'
我是这样理解的
temp
CTE 计算之前的rs_date
,然后用它来求和push-outs(因为你不能有解析sum
聚合中的函数)。
SQL> WITH
2 temp
3 AS
4 (SELECT so_number,
5 rev_number,
6 line_number,
7 rs_date,
8 status,
9 LAG (rs_date) OVER (PARTITION BY so_number ORDER BY rev_number) prev_rs_date
10 FROM zzenp_so_multi_rs)
11 SELECT z.so_number,
12 z.line_number,
13 (SELECT MAX (b.rev_number)
14 FROM zzenp_so_multi_rs b
15 WHERE b.so_number = z.so_number
16 AND b.status = 'Open') rev_number,
17 (SELECT MAX (b.rs_date)
18 FROM zzenp_so_multi_rs b
19 WHERE b.so_number = z.so_number
20 AND b.status = 'Open') rs_date,
21 SUM (CASE WHEN z.rs_date > z.prev_rs_date THEN 1 ELSE 0 END) l_sum
22 FROM temp z
23 GROUP BY z.so_number, z.line_number
24 ORDER BY z.so_number;
SO_NUMBER LINE_NUMBER REV_NUMBER RS_DATE L_SUM
------------------------------ ----------- ---------- ---------- ----------
10000 1 6 17.05.2022 2
10001 1 5 13.05.2022 1
SQL>
对于 Oracle 12.1 及更高版本,您可以使用 match_recognize
来获得干净、优雅的解决方案。
select so_number, rev_number, line_number, rs_date, no_of_push_outs
from zzenp_so_multi_rs
match_recognize (
partition by so_number, line_number
order by rev_number
measures last(rev_number) as rev_number,
count(up.*) as no_of_push_outs,
last(rs_date) as rs_date
pattern ( (up|other)* )
define up as rs_date > prev(rs_date)
);
还使用 LAG()
获取日期数量增加,但希望更简单的加入
with pout as (
select so_number, count(*) no_of_push_outs from (
select z.so_number, rs_date,
lag(rs_date) over (partition by so_number order by rev_number) p_rs_date
from zzenp_so_multi_rs z
)
where rs_date > p_rs_date
group by so_number
)
select z.*, pout.no_of_push_outs
from zzenp_so_multi_rs z, pout
where z.so_number=pout.so_number
and z.status='Open';
您可以使用 LAG
和 COUNT
分析函数(没有任何 self-joins):
SELECT *
FROM (
SELECT so_number,
rev_number,
line_number,
rs_date,
status,
COUNT(is_push_out) OVER (PARTITION BY so_number) AS no_of_push_outs
FROM (
SELECT z.*,
CASE
WHEN LAG(rs_date) OVER (PARTITION BY so_number ORDER BY rev_number)
< rs_date
THEN 1
END AS is_push_out
FROM zzenp_so_multi_rs z
)
)
WHERE status = 'Open';
或者,您可以使用 LAG
分析函数,然后使用 GROUP BY
和 KEEP (DENSE_RANK LAST ORDER BY rev_number)
获取聚合函数中最后修订的数据:
SELECT so_number,
MAX(rev_number) AS rev_number,
MAX(line_number) KEEP (DENSE_RANK LAST ORDER BY rev_number)
AS line_number,
MAX(rs_date) KEEP (DENSE_RANK LAST ORDER BY rev_number)
AS rs_date,
MAX(status) KEEP (DENSE_RANK LAST ORDER BY rev_number)
AS status,
COUNT(is_push_out) AS no_of_push_outs
FROM (
SELECT z.*,
CASE
WHEN LAG(rs_date) OVER (PARTITION BY so_number ORDER BY rev_number)
< rs_date
THEN 1
END AS is_push_out
FROM zzenp_so_multi_rs z
)
GROUP BY so_number;
其中,对于示例数据,都输出:
SO_NUMBER REV_NUMBER LINE_NUMBER RS_DATE STATUS NO_OF_PUSH_OUTS 10000 6 1 17-MAY-22 Open 2 10001 5 1 13-MAY-22 Open 1
db<>fiddle here