I have a table with accidents (~110,000 records) and a table with municipalities (~400 records). All accidents have a municipality code of the municipality where they occurred and I can count the number of accidents per municipality. For my project I need numbers / municipality.
One of the columns of the accidents table contains the type of object against which the accident occurred, eg car, truck, bicycle, etc. What I would like is to create new columns for each object type (car, truck, etc) with a count for each municipality.
Edit
Example of accidents table
mun_code objecttype
1 car
1 truck
1 car
2 bicycle
2 car
2 bicycle
2 truck
3 tree
Desired output
mun_code car truck bicycle tree
1 2 1 null null
2 1 1 2 null
3 null null null 1
Instead of null, 0 is ok.
Edit 2
The point is that I have many columns that I have to aggregate over municipalities. I just wonder whether it is possible to have a script that automatically creates the needed columns for each objecttype and automatically aggregates for each objecttype
Is this possible to do in (postgres) SQL and how should I do this?
Creating a pivot table can be achieved by using GROUP BY
and FILTER
clause
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
If you really need NULL
values instead of 0
, you can use the NULLIF()
function afterwards
NULLIF(COUNT(*) FILTER (WHERE object = 'car'), 0)
Edit: For dynamic numbers of columns, which is not simply achieveable, there is a small workaround using JSON:
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
With this, instead doing
SELECT car FROM my_pivoted_result
you can do:
SELECT jsonobject ->> 'car' FROM my_pivoted_result
you can use conditional aggregaiton
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.