SQL Server: несколько операций в одной части - PullRequest
0 голосов
/ 10 октября 2018

У меня есть этот случай как часть более крупного оператора 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

Другими словамиЯ хотел бы выполнить несколько операций как часть заявления затем.Я нигде не мог найти пример для этого.

Я не могу написать, если еще, потому что мне нужно сделать несколько объединений и опираться на данные из нескольких таблиц.Есть ли способ написать дело так, как я хотел бы?

Ответы [ 3 ]

0 голосов
/ 10 октября 2018

Я не знаком с способом сделать это с 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' 
0 голосов
/ 17 октября 2018

Еще один способ переписать этот и более читаемый -

.
.
.
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'
0 голосов
/ 10 октября 2018

A 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...