我有一个包含日期列的表.
ID | Date
----|-----------
1 | 2000-01-01
2 | 2000-02-01
3 | 2000-02-01
4 | 2000-03-01
Run Code Online (Sandbox Code Playgroud)
我需要一个select,它返回每行,ID,Date和最小日期(表中所有日期),大于当前日期.
ID | Date | Next date
----+------------+------------
1 | 2000-01-01 | 2000-02-01
2 | 2000-02-01 | 2000-03-01
3 | 2000-02-01 | 2000-03-01
4 | 2000-03-01 | (NULL)
Run Code Online (Sandbox Code Playgroud)
我的第一个方法是
SELECT id, date, LEAD (date, 1) OVER (ORDER BY date NULLS LAST) AS next_date
FROM t
Run Code Online (Sandbox Code Playgroud)
但这只有在DATE列中的值是唯一的情况下才有效.
有任何想法吗?
您可以使用带有窗口子句的分析函数.lead()不支持窗口子句,所以你需要使用一个喜欢min()或者first_value():
FIRST_VALUE ("Date")
OVER (ORDER BY "Date" RANGE BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
Run Code Online (Sandbox Code Playgroud)
默认的窗口子句是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,它将为您的所有行提供相同的值,2000-01-01并且使用ROWS窗口会遇到lead()与重复日期相同的问题(ID 2仍然会得到2000-02-01; 2000-03-01如果ID 2将获得而不是null,如果你用过ROWS BETWEEN CURRENT ROW...而不是1 FOLLOWING).
使用此范围进行演示:
with t (ID, "Date") as (
select 1, date '2000-01-01' from dual
union all select 2, date '2000-02-01' from dual
union all select 3, date '2000-02-01' from dual
union all select 4, date '2000-03-01' from dual
)
select id, "Date", FIRST_VALUE ("Date") OVER (ORDER BY "Date"
RANGE BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) AS next_date
FROM t;
ID Date NEXT_DATE
---------- ---------- ----------
1 2000-01-01 2000-02-01
2 2000-02-01 2000-03-01
3 2000-02-01 2000-03-01
4 2000-03-01
Run Code Online (Sandbox Code Playgroud)
仅考虑日期值高于当前行的行.而这仍然只需要打一次.
(我"Date"输入双引号,因为它date是一个保留字;从你的示例数据看起来它看起来像一个带引号的标识符,但它没有在你的查询中引用,所以它可能只是一个更合理的名字......)
小智 5
select * , (select min(t2.date) from table t2 where t2.date > t1.date)
from Table t1
Run Code Online (Sandbox Code Playgroud)
上面的代码在sql server中
| 归档时间: |
|
| 查看次数: |
2431 次 |
| 最近记录: |