SQL - 以列值作为列名的聚合
Posted
技术标签:
【中文标题】SQL - 以列值作为列名的聚合【英文标题】:SQL - aggregation with column value as column name 【发布时间】:2016-09-14 14:16:27 【问题描述】:对于像下面这样的表需要进行聚合,以便对于一列中的每个唯一字段,需要找到另一列中离散值的出现次数
输入表是:
id model datetime driver distance
---|-----|------------|--------|---------
1 | S | 04/03/2009 | john | 399
2 | X | 04/03/2009 | juliet | 244
3 | 3 | 04/03/2009 | borat | 555
4 | 3 | 03/03/2009 | john | 300
5 | X | 03/03/2009 | juliet | 200
6 | X | 03/03/2009 | borat | 500
7 | S | 24/12/2008 | borat | 600
8 | X | 01/01/2009 | borat | 700
需要输出
model john juliet | borat
-----|--------|-------|------
S | 1 | 0 | 1
X | 0 | 2 | 2
3 | 1 | 0 | 1
一种可能的方法是按model
进行分组,聚合如下
SUM (CASE WHEN driver = 'value' THEN 1 ELSE 0 END) AS value
用于 driver
列的每个离散值。但挑战有时是离散值的数量太多(在我的情况下约为 50),或者在某些情况下甚至不知道所有可能的离散值 - 我想知道是否有其他方法可以做到这一点。
【问题讨论】:
Dynamic pivot query using PostgreSQL 9.3的可能重复 首先进行聚合,然后进行枢轴 【参考方案1】:聚合部分需要做更多的工作。
这里有详细信息:
需要先计算所有的组合是什么 然后使用LEFT JOIN
得到哪个组合没有数据。
DEMO
WITH "allDrivers" as (
SELECT DISTINCT "driver"
FROM Table1
),
"allModels" as (
SELECT DISTINCT "model"
FROM Table1
),
"source" as (
SELECT d."driver", m."model"
FROM "allDrivers" d
CROSS JOIN "allModels" m
)
SELECT s."model", s."driver", COUNT(t."datetime")
FROM "source" s
LEFT JOIN table1 t
ON s."model" = t."model"
AND s."driver" = t."driver"
GROUP BY s."model", s."driver"
输出
| model | driver | count |
|-------|--------|-------|
| 3 | borat | 1 |
| 3 | john | 1 |
| 3 | juliet | 0 |
| S | borat | 1 |
| S | john | 1 |
| S | juliet | 0 |
| X | borat | 2 |
| X | john | 0 |
| X | juliet | 2 |
然后你可以做 dynamic pivot
【讨论】:
你能试试我的答案吗?以上是关于SQL - 以列值作为列名的聚合的主要内容,如果未能解决你的问题,请参考以下文章