带有逻辑的SQL Case语句,它是现有逻辑的子集

时间:2017-01-12 00:44:20

标签: sql if-statement logic case

假设我有一个数据集如下:

+----------+-------+----------+
| Customer | Price | Order ID |
+----------+-------+----------+
| john     | 4     | 1        |
| john     | 7     | 2        |
| mike     | 12    | 3        |
| mike     | 3     | 4        |
| stacy    | 3     | 5        |
| stacy    | 8     | 6        |
+----------+-------+----------+

我想创建一个报告,给出2组及其价格总和,一组用于GROUP A [john + mike + stacy],另一组用于GROUP B [john + mike]。
当我尝试在SQL语句中编写逻辑时出现问题 因为GROUP B是GROUP A的子集,所以case语句在到达GROUP B的逻辑之前退出。 假设我使用此代码:

with grouped_prices as (
select
case when customer in ('john', 'mike', 'stacy') then 'GROUP A'
when customer in ('john', 'mike') then 'GROUP B'
else null end as customer_groups
, price
from mytable
)
select
customer_groups
, sum(price) as total
from grouped_prices
group by customer_groups

这会产生结果

+-----------------+-------+
| customer_groups | total |
+-----------------+-------+
| GROUP A         | 37    |
+-----------------+-------+

但我想要的是

+-----------------+-------+
| customer_groups | total |
+-----------------+-------+
| GROUP A         | 37    |
+-----------------+-------+
| GROUP B         | 26    |
+-----------------+-------+  

我可以使用UNION ALL语句实现此解决方案,但我必须扫描表两次,这样效率不高。有没有比UNION ALL更聪明的解决方案,我看不到?

1 个答案:

答案 0 :(得分:1)

更新了答案

您可以加入到动态创建的派生表中,如下所示:

select sum(cp.Price) as Total, t.Group
from CustomerPrices cp
join
    (select 'Joe' as Customer, 'Group A' as Group
    union all
    select 'Sam' as Customer, 'Group A' as Group
    union all
    select 'John' as Customer, 'Group A' as Group
    union all
    select 'Joe' as Customer, 'Group B' as Group
    union all
    select 'John' as Customer, 'Group B' as Group) as t on t.Customer = cp.Customer
group by t.Group