Подтвердить что ты не робот

Как я могу выбрать несколько столбцов в CASE WHEN на SQL Server?

Я искал этот сайт широко, но не могу найти решение.

Вот пример моего запроса:

SELECT 
   ActivityID,

   Hours = (CASE 
                WHEN ActivityTypeID <> 2 THEN
                     FieldName = (Some Aggregate Sub Query),
                     FieldName2 = (Some other aggregate sub query)
                WHEN ActivityTypeID = 2 THEN
                     FieldName = (Some Aggregate Sub Query with diff result),
                     FieldName2 = (Some Other Aggregate Sub Query with diff result)
           END)

Очевидно, я оставляю много запросов, я просто хотел посмотреть, возможно ли это.

Я знаю, что, вероятно, я мог бы просто сделать "CASE" дважды, но решил, что спрошу...

Спасибо!

4b9b3361

Ответ 1

Проблема заключается в том, что оператор CASE не будет работать так, как вы его пытаетесь использовать. Вы можете использовать его только для переключения значения одного поля в запросе. Если я понимаю, что вы пытаетесь сделать, вам может понадобиться следующее:

SELECT 
   ActivityID,
   FieldName = CASE 
                  WHEN ActivityTypeID <> 2 THEN
                      (Some Aggregate Sub Query)
                  ELSE
                     (Some Aggregate Sub Query with diff result)
               END,
   FieldName2 = CASE
                  WHEN ActivityTypeID <> 2 THEN
                      (Some Aggregate Sub Query)
                  ELSE
                     (Some Aggregate Sub Query with diff result)
               END

Ответ 2

Нет, CASE является функцией и может возвращать только одно значение. Я думаю, вам придется дублировать логику CASE.

Другой вариант заключается в том, чтобы обернуть весь запрос с помощью IF и иметь два отдельных запроса для возврата результатов. Не видя остальной части запроса, трудно сказать, будет ли это работать для вас.

Ответ 3

"Случай" может возвращать только одно значение, но вы можете использовать сложный тип:

create type foo as (a int, b text);
select (case 1 when 1 then (1,'qq')::foo else (2,'ww')::foo end).*;

Ответ 4

Собственно, вы можете это сделать.

Хотя, кто-то должен отметить, что повторение операторов CASE не так плохо, как кажется. Оптимизатор запросов SQL Server достаточно умен, чтобы не выполнять CASE дважды, чтобы из-за этого вы не получили ни одной производительности.

Кроме того, кто-то может использовать следующую логику, чтобы не повторять CASE (если вам это подходит).

INSERT INTO dbo.T1
(
    Col1,
    Col2,
    Col3
)
SELECT
    1,
    SUBSTRING(MyCase.MergedColumns, 0, CHARINDEX('%', MyCase.MergedColumns)),
    SUBSTRING(MyCase.MergedColumns, CHARINDEX('%', MyCase.MergedColumns) + 1, LEN(MyCase.MergedColumns) - CHARINDEX('%', MyCase.MergedColumns))
FROM
    dbo.T1 t
LEFT OUTER JOIN
(
    SELECT CASE WHEN 1 = 1 THEN '2%3' END MergedColumns
) AS MyCase ON 1 = 1

Это будет вставлять значения (1, 2, 3) для каждой записи в таблице T1. Для разделения разделенных столбцов используется разделитель '%'. Вы можете написать свою собственную функцию разделения в зависимости от ваших потребностей (например, для обработки нулевых записей или использования сложного разделителя для полей varchar и т.д.). Но основная логика заключается в том, что вы должны присоединиться к оператору CASE и выбрать из набора результатов соединения с помощью разделенной логики.