作为 vals 外部应用的案例陈述

Case Statement as vals Outer Apply

我正在尝试将计算列添加到 table。目前我有以下 CASE 语句在 SELECT 语句中构建计算列,

--但我想使用此列来确定后续列(sooo.. 添加计算列在某种程度上是一种解决方法,可以避免复杂的 CTE,我不确定我能弄清楚 - 让我知道 CTE或者函数是更好的方法)

--- 我希望 CASE 语句成为 table 本身

中的一个计算列
SELECT top 1000
L.[MsgDate]
,C.[AlarmType]
,L.[Type]
,L.[UsrStr1]
,L.[UsrStr4]
,L.[UsrStr5]
,L.[UsrStr12]
,L.[UsrStr15]
,CASE
    WHEN EXISTS 
    (
    SELECT *
    FROM   Breinigsville.dbo.SCADA_SR S
    WHERE  S.SCADA_SR_TAG = L.UsrStr15 and 
            ((L.[UsrStr4]='analog' and C.[AlarmType] like '%HH%') or (L.[UsrStr4]='status'))
    )
        THEN 1
        ELSE 0
    END AS [Safety]



FROM [Breinigsville].[dbo].[LMFW] L


  full outer join [Breinigsville].[dbo].[_AcknowledgedAlarms] C
  on
  L.SeqNo=C.SeqNo2



  WHERE (
L.[Type]='Ack' AND 
L.UsrStr12 LIKE '%CCXOS%' AND 
L.UsrStr12 NOT LIKE '%CCXOS5' AND 
L.UsrStr12 NOT LIKE '%CCXOS6' AND 
L.UsrStr12 NOT LIKE '%CCXOS9' AND 
L.UsrStr12 NOT LIKE '%CCXOS12' AND 
L.MsgDate>getdate()-1


)

order by L.SeqNo desc

使用outer apply:

FROM [Breinigsville].[dbo].[LMFW] L full outer join
     [Breinigsville].[dbo].[_AcknowledgedAlarms] C
     on L.SeqNo = C.SeqNo2 OUTER APPLY
     (SELECT (CASE WHEN COUNT(*) > 0 THEN 1 ELSE 0 END) as Safety
      FROM   Breinigsville.dbo.SCADA_SR S
      WHERE  S.SCADA_SR_TAG = L.UsrStr15 and 
             ((L.[UsrStr4] = 'analog' and C.[AlarmType] like '%HH%') or
              (L.[UsrStr4] = 'status')
             )
     ) vals

然后您可以在查询中的任何地方使用 vals.Safety

注:此版本使用count(*)。如果性能是一个问题,那么您可以使用额外的子查询获得您想要的。我这样回答,因为查询的结构似乎更容易理解。

顺便说一下,您不能轻易地将子查询作为计算列放入。您可以这样做,但它需要创建一个用户定义的函数,并将其用于计算列。 OUTER APPLY 肯定更简单,您甚至可以将此逻辑放入 table 值函数或视图中。