Как я могу выбрать несколько столбцов в 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" дважды, но решил, что спрошу...
Спасибо!
Ответы
Ответ 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
и выбрать из набора результатов соединения с помощью разделенной логики.