想象一下,我经营一家杂货店,并希望了解我的产品的受欢迎程度。
如何从表fruit
中获取每个产品的总计,其中1
表示订单中存在产品,null
- 缺席。
order | apples | oranges | kiwis
================================
1 | 1 | 1 |
2 | | 1 |
3 | | 1 | 1
4 | 1 | | 1
5 | 1 | 1 | 1
我追求的结果是:
apples: 3
oranges: 4
kiwis: 3
到目前为止我尝试过:
select count(*) from fruit where apples = '1'
union
select count(*) from fruit where oranges = '1'
union
select count(*) from fruit where kiwis = '1'
这样可行,但我不知道哪一行对应哪个产品。
答案 0 :(得分:2)
您可以使用UNPIVOT
将列转换为行,它们会计算每个水果的行数:
SELECT upvt.FruitName,
[Count] = COUNT(*)
FROM fruit AS f
UNPIVOT
( HasFruit
FOR FruitName IN ([Apples], [Oranges], [Kiwis])
) AS upvt
GROUP BY upvt.FruitName;
如果删除聚合函数,您可以看到unpivot正在做什么,以下查询:
SELECT upvt.*
FROM (VALUES
(1,1,1,NULL),
(2,NULL,1,NULL),
(3,NULL,1,1),
(4,1,NULL,1),
(5,1,1,1)
) AS f ([Order], apples, oranges, Kiwis)
UNPIVOT
( HasFruit
FOR FruitName IN ([Apples], [Oranges], [Kiwis])
) AS upvt;
将屈服:
Order HasFruit FruitName
------------------------------
1 1 apples
1 1 oranges
2 1 oranges
3 1 oranges
3 1 Kiwis
4 1 apples
4 1 Kiwis
5 1 apples
5 1 oranges
5 1 Kiwis
然后它只是一个简单的组,并计数得到你想要的结果。如果您还可以使用0
列来表明它不存在,那么请将您的计数更改为COUNT(NULLIF(upvt.HasFruit, 0))
答案 1 :(得分:1)
添加额外的列以识别产品:
select 'apples' as productName, count(*) from fruit where apples = '1'
union
select 'oranges', count(*) from fruit where oranges = '1'
union
select 'kiwis', count(*) from fruit where kiwis = '1'