【问题标题】:SQL Server : case multiple operations in then partSQL Server:在then部分中进行多个操作
【发布时间】:2018-10-10 14:30:47
【问题描述】:

我将此案例作为更大 SQL 语句的一部分:

.
.
.
CASE    
   WHEN [AEC].item = 'S' THEN [sOld].code
   WHEN [AEC].item= 'R' THEN [rOld].code
END AS [oldCode],

CASE    
   WHEN [AEC].item= 'S' THEN [sOld].system
   WHEN [AEC].item= 'R' THEN [rOld].system
END AS [oldStatusSystem],

CASE    
   WHEN [AEC].item= 'S' THEN [sNew].code
   WHEN [AEC].item= 'R' THEN [rNew].code
END AS [newCode],

CASE     
   WHEN [AEC].item= 'S' THEN [sNew].system
   WHEN [AEC].item= 'R' THEN [rNew].system
END AS [newStatusSystem],
.
.

LEFT JOIN 
    tblSystemStatuses AS [sOld] ON [AEC].oldValue = [sOld].status
LEFT JOIN
    tblSystemStatuses AS [sNew] ON [AEC].newValue = [sNew].status
LEFT JOIN
    tblSystemRoles AS [rOld] ON [AEC].oldValue = [rOld].role
LEFT JOIN
    tblSystemRoles AS [rNew] ON [AEC].newValue = [rNew].role

我希望这个案子看起来像这样:

CASE    
   WHEN [AEC].item = 'S' 
      THEN 
           [sOld].code AS [oldCode],
           [sOld].system AS [oldStatusSystem],
           [sNew].code AS [newCode], 
           [sNew].system AS [newStatusSystem]
   ELSE WHEN [AEC].item = 'R' 
      THEN 
           [rOld].code AS [oldCode],
           [rOld].system AS [oldStatusSystem],
           [rNew].code AS [newCode], 
           [rNew].system AS [newStatusSystem]
  END

换句话说,我想在 then 语句中执行一些操作。我在任何地方都找不到这样的例子。

我不能写 if else 因为我需要进行一些连接并依赖来自多个表的数据。有没有办法按照我想要的方式写案例?

【问题讨论】:

  • 我不认为这是可能的,因为 case 是一个“返回”某些东西的函数,如果你在 NPP 或 SSMS 上编码,你可以在垂直选择的多行上写相同的内容:按住 alt +shift
  • 不。 Case 是一个表达式,它返回一个标量值。

标签: sql-server tsql case


【解决方案1】:

case 表达式只返回一个值。所以,你不能为所欲为。

您可以简化逻辑,但方式略有不同。可能最好的方法是使用cross apply。请注意,这在from 子句中,因为select 中的表达式只能返回标量值。所以,你需要在select中选择你想要的列:

select v.oldcode, . . . 
from . . . cross apply
     (select v.*
      from (values ('S', [sOld].code, [sOld].system, [sNew].code, [sNew].system),
                   ('R', [rOld].code, [rOld].system, [rNew].code, [rNew].system)
           ) v(item, oldcode, oldsystem, newcode, newsystem)
      where v.item = [AEC].item
     ) v

这满足了与单个 case 表达式相同的需求。值得注意的是,匹配逻辑只出现一次。此版本的优点是可以在select 中的多个表达式中使用各个字段。

【讨论】:

  • @Polina 。 . .你有理由不接受这个答案吗?你已经接受了它,它似乎比一堆left joins 简单。
【解决方案2】:

我不熟悉使用CASE EXPRESSION 的方法,但您可以使用UNION

SELECT [sOld].code as [oldCode],
       [sOld].system as [oldStatusSystem],
       [sNew].code as [newCode], 
       [sNew].system as [newStatusSystem]
FROM ...
WHERE [AEC].item = 's' 
UNION ALL 
SELECT [rOld].code as [oldCode],
       [rOld].system as [oldStatusSystem],
       [rNew].code as [newCode], 
       [rNew].system as [newStatusSystem]
FROM ...
WHERE [AEC].item = 'r' 

【讨论】:

    【解决方案3】:

    另一种重写这个更易读的方法是

    .
    .
    .
    ISNULL([sOld].code, [rOld].code) AS [oldCode],
    ISNULL([sOld].system, [rOld].system) AS [oldStatusSystem],
    ISNULL([sNew].code, [rNew].code) AS [newCode],
    ISNULL([sNew].system, [rNew].system) AS [newStatusSystem],
    .
    .
    .
    LEFT JOIN tblSystemStatuses  AS [sOld]
        ON [AEC].oldValue = [sOld].status
        AND [AEC].item = 's'
    LEFT JOIN tblSystemStatuses 
        ON [AEC].newValue = [sNew].status
        AND [AEC].item = 's'
    LEFT JOIN tblSystemRoles 
        ON [AEC].oldValue = [rOld].role
        AND [AEC].item = 'r'
    LEFT JOIN tblSystemRoles 
        ON [AEC].newValue = [rNew].role
        AND [AEC].item = 'r'
    

    【讨论】:

      猜你喜欢
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 2021-02-03
      • 2022-06-13
      • 1970-01-01
      • 1970-01-01
      • 2023-01-09
      • 1970-01-01
      相关资源
      最近更新 更多