I have a table with two columns (type, id) that has the following structure:
id | type |
---|---|
A123 | ACCOUNT |
C123 | CLIENT |
O123 | ORDER |
A124 | ACCOUNT |
O124 | ORDER |
C125 | CLIENT |
I want to be able to do a SELECT on this table with alias columns of account_id_column, client_id_column and order_id_column where it groups it by type into three different columns like the following:
account_id_column | client_id_column | order_id_column |
---|---|---|
A123 | C123 | O123 |
A124 | C125 | O124 |
But not sure how to do this? Do I have to use a JOIN on the tables and then use a where clause on the type and then group by on it?
SQL queries are row based, but you want columns. This requires a pivot. We need something in common for each row so we can group them together. We can add a row_number to each row to put them in order. Then we pivot them into individual columns by grouping by the row number.
with ordered_things as (
select
row_number() over(partition by type order by id asc) as rn,
id, type
from things
)
select
coalesce(max(id) filter(where type = 'ACCOUNT'), '') as account_id,
coalesce(max(id) filter(where type = 'CLIENT'), '') as client_id,
coalesce(max(id) filter(where type = 'ORDER'), '') as order_id
from ordered_things
group by rn
order by rn
Since we know there's only one ID for each type in the group, max(id)
is just a way to satisfy the need for each column of a group by query to be an aggregated function.
coalesce
just gets rid of unsightly nulls when there isn't an equal number of ids for each type.