Comment sélectionner plusieurs colonnes dans un CASE WHEN sur SQL Server?
J'ai effectué des recherches approfondies sur ce site, mais je ne trouve pas de solution.
Voici l'exemple de ma requête:
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)
évidemment je laisse de côté une grande partie de la requête, je voulais juste voir si c'était possible.
Je sais que je pourrais probablement faire le "CASE" deux fois mais je me suis dit que je demanderais ...
Le problème est que l'instruction CASE
ne fonctionnera pas de la même manière que vous essayez de l'utiliser. Vous ne pouvez l'utiliser que pour changer la valeur d'un champ dans une requête. Si je comprends ce que vous essayez de faire, vous pourriez avoir besoin de ceci:
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
Non, CASE
est une fonction et ne peut renvoyer qu'une seule valeur. Je pense que vous allez devoir dupliquer votre logique CASE.
L'autre option consisterait à envelopper la requête entière avec un IF et à avoir deux requêtes distinctes pour renvoyer les résultats. Sans voir le reste de la requête, il est difficile de dire si cela fonctionnerait pour vous.
"Case" peut renvoyer une seule valeur, mais vous pouvez utiliser un type complexe:
create type foo as (a int, b text);
select (case 1 when 1 then (1,'qq')::foo else (2,'ww')::foo end).*;
En fait, vous pouvez le faire.
Bien que quelqu'un devrait noter que répéter les déclarations CASE
n'est pas si mal qu'il y paraît. L'optimiseur de requêtes de SQL Server est suffisamment intelligent pour ne pas exécuter la CASE
afin de ne pas nuire aux performances à cause de cela.
De plus, quelqu'un pourrait utiliser la logique suivante pour ne pas répéter le CASE (si cela vous convient ..)
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
Cela insérera les valeurs (1, 2, 3) pour chaque enregistrement de la table T1
. Ceci utilise un délimiteur '%'
pour fractionner les colonnes fusionnées. Vous pouvez écrire votre propre fonction de partage en fonction de vos besoins (par exemple, pour gérer des enregistrements nuls ou utiliser un délimiteur complexe pour les champs varchar
, etc.). Mais la logique principale est que vous devez joindre l'instruction CASE
et sélectionner dans l'ensemble de résultats de la jointure en utilisant une logique de division.