如何根据另一列的值创建列?

时间:2019-08-22 13:27:34

标签: sql postgresql

我有一个带事故的表(约110,000条记录)和一个有市政当局的表(约400条记录)。所有事故都有发生事故的地方的市镇代码,我可以算出每个市镇的事故数量。对于我的项目,我需要数字/市政府。

事故表的一列包含发生事故的对象的类型,例如我想要为每种对象类型(汽车,卡车等)创建新列,并为每个城市创建一个计数。

修改

事故表示例

mun_code objecttype
1        car
1        truck
1        car
2        bicycle
2        car
2        bicycle
2        truck
3        tree

所需的输出

mun_code car truck bicycle tree
1        2   1     null    null
2        1   1     2       null
3        null null null    1

0也可以代替null。

编辑2

重点是,我必须汇总许多直辖市的列。我只是想知道是否可以使用一个脚本为每个对象类型自动创建所需的列并为每个对象类型自动聚合

这可以在(postgres)SQL中执行吗?

2 个答案:

答案 0 :(得分:2)

demo:db<>fiddle

可以使用GROUP BYFILTER子句来创建数据透视表

SELECT
    mun_code,
    COUNT(*) FILTER (WHERE object = 'car') as car,
    COUNT(*) FILTER (WHERE object = 'truck') as truck,
    COUNT(*) FILTER (WHERE object = 'bike') as bike,
    COUNT(*) FILTER (WHERE object = 'tree') as tree
FROM
    mytable
GROUP BY mun_code

如果您确实需要NULL值而不是0,则可以在以后使用NULLIF()函数

demo:db<>fiddle

NULLIF(COUNT(*) FILTER (WHERE object = 'car'), 0)

编辑:对于无法简单实现的动态列数,有一个使用JSON的小解决方法:

demo:db<>fiddle

SELECT
    mun_code,
    jsonb_object_agg(object, count) AS jsonobject
FROM (
    SELECT
        mun_code,
        object,
        COUNT(*)
    FROM
        mytable t
    GROUP BY mun_code, object
) s
GROUP BY mun_code

用这个代替,

SELECT car FROM my_pivoted_result

您可以这样做:

SELECT jsonobject ->> 'car' FROM my_pivoted_result

答案 1 :(得分:0)

您可以使用条件性聚集地

    select sum(case when type='car' then 1 else 0 end) as car,
    sum(case when type='truck' then 1 else 0 end) as truck,
    sum(case when type='bicycle' then 1 else 0 end) as bicycle