[英]How can I get the date with the closest previous month from a given row date in a partition?
I have the table A 我有桌子A
Item Date
a 01-01-2000
a 10-05-2000
a 12-02-2000
b 01-01-2000
b 01-31-2000
b 02-01-2000
c 01-01-2000
i want this output, the closest previous date of the given row for the same item 我想要此输出,同一项目的给定行的最接近的上一个日期
Item Date closest_day
a 01-01-2000 null
a 10-05-2000 01-01-2000
a 12-02-2000 10-05-2000
b 01-01-2000 null
b 01-31-2000 null
b 02-01-2000 01-31-2000
c 01-01-2000 null
try this 尝试这个
with t as(
select 'a' c,to_date('01.01.2000','mm.dd.yyyy') d from dual
union all
select 'a' ,to_date('10.05.2000','mm.dd.yyyy') from dual
union all
select 'a' ,to_date('12.02.2000','mm.dd.yyyy') from dual
union all
select 'b' ,to_date('01.01.2000','mm.dd.yyyy') from dual
union all
select 'b' ,to_date('01.31.2000','mm.dd.yyyy') from dual
union all
select 'b' ,to_date('02.01.2000','mm.dd.yyyy') from dual
union all
select 'c' ,to_date('01.01.2000','mm.dd.yyyy') from dual
)
select t.c,t.d,LAG (t.d) over ( partition by t.c order by t.d ) from t
closest date must be in a different month? 最接近的日期必须在不同的月份? ok
好
with t as(
select 'a' c,to_date('01.01.2000','mm.dd.yyyy') d from dual
union all
select 'a' ,to_date('10.05.2000','mm.dd.yyyy') from dual
union all
select 'a' ,to_date('12.02.2000','mm.dd.yyyy') from dual
union all
select 'b' ,to_date('01.01.2000','mm.dd.yyyy') from dual
union all
select 'b' ,to_date('01.31.2000','mm.dd.yyyy') from dual
union all
select 'b' ,to_date('02.01.2000','mm.dd.yyyy') from dual
union all
select 'c' ,to_date('01.01.2000','mm.dd.yyyy') from dual
)
select c,d,case when trunc(d,'Month')<>trunc(closest_d,'Month') then closest_d else null end closest_d from(
select t.c,t.d,LAG (t.d) over ( partition by t.c order by t.d ) closest_d from t
)
You can use a self-left join containing inequality among dates within the join condition : 您可以使用包含连接条件内日期之间不等式的自左连接:
with t2 as
(
select t1.Item,t1."Date" as t1_Date, t2."Date" as t2_Date
from t t1
left join t t2 on t1."Date">t2."Date" and t1.Item = t2.Item
)
select Item, t1_Date as "Date", max(t2_Date) as "Closest Day"
from t2
group by Item, t1_Date
order by Item, t1_Date
i want this output, the closest previous date of the given row for the same item
我想要此输出,同一项目的给定行的最接近的上一个日期
That's exactly what window function lag()
does: 这正是窗口函数
lag()
作用:
select
t.*,
lag(date) over(partition by item order by date) closest_day
from mytable t
From the question title: 从问题标题:
How can I get the date with the closest previous month from a given row date in a partition?
如何从分区中给定的行日期中获取最近的上个月的日期?
This is specifically addressing the fact that the previous value should be in a "previous" month and not in the same month as the row's date as per the expected results in Edits 1 through Edit 3 . 这是专门针对以下事实:根据编辑1到编辑3中的预期结果,前一个值应位于“上一个”月中,而不应与行日期位于同一月中。
Oracle Setup : Oracle安装程序 :
CREATE TABLE test_data ( item, "date" ) AS
SELECT 'A', DATE '2000-01-01' FROM DUAL UNION ALL
SELECT 'A', DATE '2000-10-05' FROM DUAL UNION ALL
SELECT 'A', DATE '2000-12-02' FROM DUAL UNION ALL
SELECT 'B', DATE '2000-01-01' FROM DUAL UNION ALL
SELECT 'B', DATE '2000-01-31' FROM DUAL UNION ALL
SELECT 'B', DATE '2000-02-01' FROM DUAL UNION ALL
SELECT 'C', DATE '2000-01-01' FROM DUAL;
Query : 查询 :
SELECT t.*,
( SELECT MAX( "date" )
FROM test_data p
WHERE p.item = t.item
AND p."date" < TRUNC( t."date", 'MM' )
) AS prev_date
FROM test_data t
Output : 输出 :
\nITEM |项目| date |
日期| PREV_DATE
PREV_DATE \n:--- |
:--- | :------------------ |
:------------------ | :------------------
:------------------\nA |
A | 2000-01-01 00:00:00 |
2000-01-01 00:00:00 | null
空值 \nA |
A | 2000-10-05 00:00:00 |
2000-10-05 00:00:00 | 2000-01-01 00:00:00
2000-01-01 00:00:00\nA |
A | 2000-12-02 00:00:00 |
2000-12-02 00:00:00 | 2000-10-05 00:00:00
2000-10-05 00:00:00\nB |
B | 2000-01-01 00:00:00 |
2000-01-01 00:00:00 | null
空值 \nB |
B | 2000-01-31 00:00:00 |
2000-01-31 00:00:00 | null
空值 \nB |
B | 2000-02-01 00:00:00 |
2000-02-01 00:00:00 | 2000-01-31 00:00:00
2000-01-31 00:00:00\nC |
C | 2000-01-01 00:00:00 |
2000-01-01 00:00:00 | null
空值 \n
You can do this with window functions -- if I assume that you want the most recent date before the current month for each row. 您可以使用窗口函数来执行此操作-如果我假设您希望每一行的当前日期之前为最新日期。 This uses the
range
window definition: 这使用
range
窗口定义:
SELECT t.*,
MAX("date") OVER (PARTITION BY item
ORDER BY TRUNC(t."date", 'MON')
RANGE BETWEEN UNBOUNDED PRECEDING AND INTERVAL '1' MONTH PRECEDING
) AS prev_date
FROM test_data t;
Here is a db<>fiddle. 这是db <>小提琴。
If you specifically want the result from the previous calendar month, then: 如果您特别想要上一个日历月的结果,则:
SELECT t.*,
MAX("date") OVER (PARTITION BY item
ORDER BY TRUNC(t."date", 'MON')
RANGE BETWEEN INTERVAL '1' MONTH PRECEDING AND INTERVAL '1' MONTH PRECEDING
) AS prev_date
FROM test_data t;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.