我有一个包含日期列的表.
ID  |      Date 
----|-----------
  1 | 2000-01-01
  2 | 2000-02-01
  3 | 2000-02-01
  4 | 2000-03-01
我需要一个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)
我的第一个方法是
SELECT id, date, LEAD (date, 1) OVER (ORDER BY date NULLS LAST) AS next_date
  FROM t
但这只有在DATE列中的值是唯一的情况下才有效.
有任何想法吗?
您可以使用带有窗口子句的分析函数.lead()不支持窗口子句,所以你需要使用一个喜欢min()或者first_value():
FIRST_VALUE ("Date")
  OVER (ORDER BY "Date" RANGE BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
默认的窗口子句是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           
仅考虑日期值高于当前行的行.而这仍然只需要打一次.
(我"Date"输入双引号,因为它date是一个保留字;从你的示例数据看起来它看起来像一个带引号的标识符,但它没有在你的查询中引用,所以它可能只是一个更合理的名字......)
小智 5
select * , (select min(t2.date) from table t2 where t2.date > t1.date)
from Table t1
上面的代码在sql server中