2017-10-13 1 views
1

Comment puis-je inclure les résultats d'une expression dans une clause GROUP BY et également sélectionner la sortie de l'expression?Comment regrouper par une expression dans TSQL et capturer le résultat?

Dire que j'ai ce tableau:

╔════════════════════════╦═══════════╦═══════╗ 
║   Forest   ║ Animal ║ Count ║ 
╠════════════════════════╬═══════════╬═══════╣ 
║ Tongass    ║ Hyena  ║ 600 ║ 
║ Tongass    ║ Bear  ║ 1200 ║ 
║ Mount Baker-Snoqualmie ║ Wolf  ║ 30 ║ 
║ Mount Baker-Snoqualmie ║ Bunny  ║  2 ║ 
║ Ozark-St. Francis  ║ Pigeon ║ 100 ║ 
║ Ozark-St. Francis  ║ Ostrich ║  1 ║ 
║ Bitterroot    ║ Tarantula ║ 9001 ║ 
╚════════════════════════╩═══════════╩═══════╝ 

je besoin d'une ligne avec le nombre de carnivores dans chaque forêt et une ligne pour le nombre des non-carnivores (s'il y en a). Ceci est la sortie que je cherche dans cet exemple:

╔════════════════════════╦═══════════════╦═══════════════╗ 
║   Forest   ║ AnimalsOfType ║ AreCarnivores ║ 
╠════════════════════════╬═══════════════╬═══════════════╣ 
║ Tongass    ║   1800 ║    1 ║ 
║ Mount Baker-Snoqualmie ║    2 ║    0 ║ 
║ Mount Baker-Snoqualmie ║   30 ║    1 ║ 
║ Ozark-St. Francis  ║   101 ║    0 ║ 
║ Bitterroot    ║   9001 ║    1 ║ 
╚════════════════════════╩═══════════════╩═══════════════╝ 

Les informations pour savoir si oui ou non un animal carnivore est codé dans l'expression.

Ce que je voudrais faire est de comprendre l'expression dans le groupe par référence et son résultat dans la clause select:

SELECT TOP (1000) 
    [Forest], 
    SUM([COUNT]) AS AnimalsOfType, 
    AreCarnivores 
FROM [Tinker].[dbo].[ForestAnimals] 
GROUP BY 
    Forest, 
    CASE WHEN ForestAnimals.Animal IN ('Pigeon', 'Ostrich', 'Bunny') THEN 0 ELSE 1 END AS AreCarnivores 

Cependant, ce n'est pas valide la syntaxe TSQL.

Si j'inclue la colonne Animal dans la clause GROUP BY pour me permettre de réexécuter la fonction dans SELECT, j'obtiendrai une ligne par type d'animal, ce qui n'est pas le comportement souhaité. Effectuer des sélections séparées dans les tables temporaires et regrouper les résultats n'est pas souhaitable car la version réelle de cette requête contient un grand nombre d'expressions qui ont besoin de ce comportement dans le même jeu de résultats, ce qui rendrait la procédure stockée extrêmement difficile.

+0

Pouvez-vous montrer la fonction? Nous devons voir les intrants et les extrants. – Parfait

+0

Je pense que "fonction" est un hareng rouge ici; il a besoin d'une expression, qui peut être ou non un UDF. –

+0

Upvoted pour les tables bien formatées! – pcdev

Répondre

2

Utilisez un CTE:

WITH X AS (
    SELECT Forest, Animal, Count, 
     CASE WHEN ForestAnimals.Animal IN ('Pigeon', 'Ostrich', 'Bunny') 
       THEN 0 
       ELSE 1 END AS AreCarnivores 
    FROM [Tinker].[dbo].[ForestAnimals] 
) 
SELECT Forest, SUM(Count) AS AnimalsOfType, AreCarnivores 
FROM X 
Group by Forest, AreCarnivores; 

Ou être plus prolixe à ce sujet et vous répéter:

SELECT Forest, SUM(Count) AS AnimalsOfType, 
     CASE WHEN ForestAnimals.Animal IN ('Pigeon', 'Ostrich', 'Bunny') 
       THEN 0 
       ELSE 1 END AS AreCarnivores 
FROM [Tinker].[dbo].[ForestAnimals] 
GROUP BY Forest, CASE WHEN ForestAnimals.Animal IN ('Pigeon', 'Ostrich', 'Bunny') 
       THEN 0 
       ELSE 1 END; 

Ils sont des requêtes équivalentes à l'optimiseur.