2017-10-13 30 views
1

如何在GROUP BY子句中包含表达式的结果并选择表达式的输出?如何通过TSQL中的表达式进行分组并捕获结果?

说我有这个表:

╔════════════════════════╦═══════════╦═══════╗ 
║   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 ║ 
╚════════════════════════╩═══════════╩═══════╝ 

我需要一排中的每个森林食肉动物的数量和非食肉动物的计数行(如果有的话)。这是我在这个例子中寻找的输出:

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

表达式中编码了动物是否是肉食性的信息。

我希望做的是包括组,通过在表达和引用其结果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 

然而,这不是有效的TSQL语法。

如果我在GROUP BY子句中包含Animal列以允许我在SELECT中重新运行该函数,那么每个动物类型将得到一行,这不是所需的行为。

做单独的选择到临时表和联合结果是不可取的,因为这个查询的真实版本具有大量需要在同一个结果集中的这种行为的表达式,这将导致非常尴尬的存储过程。

+0

你能显示该功能吗?我们需要看到输入和输出。 – Parfait

+0

我认为“功能”在这里是红鲱鱼;他需要一个表达式,可能是也可能不是UDF。 –

+0

Upvoted为格式良好的表! – pcdev

回答

2

使用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; 

或者更详细的了解它,并重复自己:

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; 

他们是等价的查询优化器。

相关问题