我有一个包含3个字段的表,如此示例表Tbl1
Person Cost FromDate
1 10 2009-1-1
1 20 2010-1-1
2 10 2009-1-1
我想查询并获取3个字段和一个名为ToDate的生成字段,默认为2099-1-1,除非表中的人员的另一个条目隐含了实际的ToDate。
select Person,Cost,FromDate,ToDate From Tbl1
Person Cost FromDate ToDate
1 10 2009-1-1 2010-1-1
1 20 2010-1-1 2099-1-1
2 10 2009-1-1 2099-1-1
答案 0 :(得分:1)
您可以从记录日期之后的所有日期中选择最短日期。如果没有,则为NULL。使用COALESCE,您可以将NULL更改为默认日期:
select
Person,
Cost,
FromDate,
coalesce((select min(FromDate) from Tbl1 later where later.FromDate > Tbl1.FromDate), '2099-01-01') as ToDate
From Tbl1
order by Person, FromDate;
答案 1 :(得分:0)
尽管Thorsten的回答非常好,但使用窗口函数来匹配派生的结束日期会更有效。
;WITH nbrdTbl
AS ( SELECT Person, Cost, FromDate, row_nr = ROW_NUMBER() OVER (PARTITION BY Person ORDER BY FromDate ASC)
FROM Tbl1)
SELECT t.Person, t.Cost, t.FromDate, derived_end_date = COALESCE(nxt.FromDate, '9991231')
FROM nbrdTbl t
LEFT OUTER JOIN nbrdTbl nxt
ON nxt.Person = t.Person
AND nxt.row_nr = t.row_nr + 1
ORDER BY t.Person, t.FromDate
根据执行计划对2000记录表进行测试,效率约为3倍(78%对22%)。