选择它也设置为可变

时间:2018-04-12 11:11:59

标签: sql-server tsql

我刚到公司工作,维持公司现有的计划。

现在我需要从表中获取数据。

所以我需要从表中做一个select,表列dateBegin也许不是null,所以如果datebegin为null,我得到datebegin2。如果为null或< = datebegin,则dateto从datebegin添加1年。

我现在所能做的就是使用case来获得正确的值。但它对代码来说太长了,难以阅读。我怎样才能实现下面的代码?谢谢你的回复...

declare @val smalldatetime

select id
     , @val = COALESCE(dateBegin, dateBegin2) as DateBegin
     , COALESCE(dateTo, dateadd(Y, 1, @val)) As DateTo 
from TblL

1 个答案:

答案 0 :(得分:1)

您无法混用此功能,但您可以使用APPLY 逐行计算其他列。这些列可以在语句中使用,类似于变量:

无法测试,但这应该等同于您的尝试:

select id
     , A.DateBegin
     , COALESCE(dateTo, dateadd(Y, 1, A.DateBegin)) As DateTo 
from TblL
CROSS APPLY(SELECT COALESCE(dateBegin, dateBegin2)) AS A(DateBegin)

说明这个想法的工作实例

DECLARE @tbl TABLE(ID INT IDENTITY, SomeString VARCHAR(500));
INSERT INTO @tbl VALUES('Find the #value# between the "#"')
                      ,('One more #example#');
SELECT t.ID
      ,t.SomeString 
      ,A.FirstHash
      ,B.SecondHash
      ,SUBSTRING(t.SomeString,A.FirstHash+1,C.FragmentLength) AS Fragment
FROM @tbl AS t      
CROSS APPLY(SELECT CHARINDEX('#',t.SomeString)) AS A(FirstHash)                  
CROSS APPLY(SELECT CHARINDEX('#',t.SomeString,A.FirstHash+1)) AS B(SecondHash)          
CROSS APPLY(SELECT B.SecondHash-A.FirstHash-1) AS C(FragmentLength);

返回

ID  SomeString                         1.#  2.# Fragment
1   Find the #value# between the "#"    10  16  value
2   One more #example#                  10  18  example

没有这个技巧的相同查询将是这样的

SELECT t.ID
      ,t.SomeString 
      ,CHARINDEX('#',t.SomeString)
      ,CHARINDEX('#',t.SomeString,CHARINDEX('#',t.SomeString)+1)
      ,SUBSTRING(t.SomeString,CHARINDEX('#',t.SomeString)+1,CHARINDEX('#',t.SomeString,CHARINDEX('#',t.SomeString)+1)-CHARINDEX('#',t.SomeString)-1) AS Fragment
FROM @tbl AS t