Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询,从表中的数据生成一个额外字段_Sql_Sql Server - Fatal编程技术网

SQL查询,从表中的数据生成一个额外字段

SQL查询,从表中的数据生成一个额外字段,sql,sql-server,Sql,Sql Server,我有一个包含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 ToDat

我有一个包含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

您可以从记录日期之后的所有日期中选择最小日期。如果没有,则返回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;

尽管托尔斯滕的答案很好,但使用窗口函数匹配派生的结束日期会更有效

;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%)。

我很困惑。
ToDate
Tbl1
中的字段吗,或者您希望通过连接添加到查询中的内容?不,它不在Tbl1中,但我正在寻找可以从Tbl1生成它的sql代码,因为计算ToDate所需的所有数据都在TB11中。那么如何从Tbl1中的字段计算ToDate呢?这几乎可以实现-只是person 2的ToDate返回为2010-01-01,而不是2099-01-01根据需要。我只是添加了额外的条件,稍后。Person=Tbl1。Person,这就解决了所有问题,非常感谢