Лучший способ сделать вложенную логику оператора case в SQL Server
в настоящее время я пишу SQL-запрос, где несколько возвращенных столбцов должны быть вычислены в зависимости от довольно большого количества условий.
в настоящее время я использую вложенные операторы case, но это становится грязным. Есть ли лучший (более организованный и/или читаемый) способ?
(Я использую Microsoft SQL Server, 2005)
упрощенный пример:
SELECT
col1,
col2,
col3,
CASE
WHEN condition
THEN
CASE
WHEN condition1
THEN
CASE
WHEN condition2
THEN calculation1
ELSE calculation2
END
ELSE
CASE
WHEN condition2
THEN calculation3
ELSE calculation4
END
END
ELSE
CASE
WHEN condition1
THEN
CASE
WHEN condition2
THEN calculation5
ELSE calculation6
END
ELSE
CASE
WHEN condition2
THEN calculation7
ELSE calculation8
END
END
END AS 'calculatedcol1',
col4,
col5 -- etc
FROM table
8 ответов:
вы можете попробовать какой-то трюк слияния, например:
SELECT COALESCE( CASE WHEN condition1 THEN calculation1 ELSE NULL END, CASE WHEN condition2 THEN calculation2 ELSE NULL END, etc... )
оберните все эти случаи в один.
SELECT col1, col2, col3, CASE WHEN condition1 THEN calculation1 WHEN condition2 THEN calculation2 WHEN condition3 THEN calculation3 WHEN condition4 THEN calculation4 WHEN condition5 THEN calculation5 ELSE NULL END AS 'calculatedcol1', col4, col5 -- etc FROM table
вы можете объединить несколько условий, чтобы избежать ситуации:
CASE WHEN condition1 = true AND condition2 = true THEN calculation1 WHEN condition1 = true AND condition2 = false ELSE 'what so ever' END,
Я лично делаю это таким образом, сохраняя встроенные выражения CASE ограниченными. Я бы также добавил комментарии, чтобы объяснить, что происходит. Если он слишком сложен, разбейте его на функции.
SELECT col1, col2, col3, CASE WHEN condition THEN CASE WHEN condition1 THEN CASE WHEN condition2 THEN calculation1 ELSE calculation2 END ELSE CASE WHEN condition2 THEN calculation3 ELSE calculation4 END END ELSE CASE WHEN condition1 THEN CASE WHEN condition2 THEN calculation5 ELSE calculation6 END ELSE CASE WHEN condition2 THEN calculation7 ELSE calculation8 END END AS 'calculatedcol1', col4, col5 -- etc FROM table
вот простое решение вложенного" сложного " случая statment: -- Вложенный Случай Сложное Выражение
select datediff(dd,Invdate,'2009/01/31')+1 as DaysOld, case when datediff(dd,Invdate,'2009/01/31')+1 >150 then 6 else case when datediff(dd,Invdate,'2009/01/31')+1 >120 then 5 else case when datediff(dd,Invdate,'2009/01/31')+1 >90 then 4 else case when datediff(dd,Invdate,'2009/01/31')+1 >60 then 3 else case when datediff(dd,Invdate,'2009/01/31')+1 >30 then 2 else case when datediff(dd,Invdate,'2009/01/31')+1 >30 then 1 end end end end end end as Bucket from rm20090131atbпросто убедитесь, что у вас есть оператор end для каждого оператора case
пользовательская функция может быть лучше сервера, по крайней мере, чтобы скрыть логику - esp. если вам нужно сделать это в более чем один запрос
мы можем объединить несколько условий вместе, чтобы уменьшить накладные расходы на производительность.
Пусть есть три переменные a b c, на которых мы хотим выполнить случаи. Мы можем сделать это, как показано ниже:
CASE WHEN a = 1 AND b = 1 AND c = 1 THEN '1' WHEN a = 0 AND b = 0 AND c = 1 THEN '0' ELSE '0' END,
Я прошел через это и нашел все ответы супер круто, однако хочет добавить к ответу, данному @deejers
SELECT col1, col2, col3, CASE WHEN condition1 THEN calculation1 WHEN condition2 THEN calculation2 WHEN condition3 THEN calculation3 WHEN condition4 THEN calculation4 WHEN condition5 THEN calculation5 END AS 'calculatedcol1', col4, col5 -- etc FROM tableвы можете сделать ELSE необязательным, поскольку он не является обязательным, это очень полезно во многих сценариях.
Comments