SQL - 以列值作为列名聚合

时间:2016-09-14 14:16:27

标签: sql postgresql pivot crosstab

对于像下面这样的表,需要进行聚合,以便对于一列中的每个唯一字段,需要在另一列中查找离散值的出现次数

输入表是:

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),或者在某些情况下甚至不知道所有可能的离散值 - 我想知道是否有另一种方法可以做到这一点。

1 个答案:

答案 0 :(得分:0)

聚合部分需要更多工作。

详情如下:

  • 首先需要计算所有组合
  • 然后使用protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) { if (Equals(storage, value)) { return false; } storage = value; this.OnPropertyChanged(propertyName); return true; } 来获取哪些组合没有数据。

<强> DEMO

LEFT JOIN

<强>输出

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"  

然后您可以执行 dynamic pivot