sql >> Database >  >> RDS >> PostgreSQL

draai/kruis verschillende rijgegevens naar kolommen met postgres

Enkele eenvoudige oplossingen die in sommige gevallen voldoende zijn. Deze tabel gebruiken (SQL Fiddle werkt momenteel niet)

create table a (
    name text,
    tag text
);
insert into a (name, tag) values
('Bob', 'sport'),
('Bob', 'action'),
('Bob', 'comedy'),
('Tom', 'action'),
('Tom', 'drama'),
('Sue', 'sport');

Een eenvoudige arrays-aggregatie als ze ergens anders kunnen worden gesplitst

select
    name,
    array_agg(tag order by tag) as tags,
    array_agg(total order by tag) as totals
from (
    select name, tag, count(a.name) as total
    from
        a
        right join (
            (select distinct tag from a) t
            cross join
            (select distinct name from a) n
        ) c using (name, tag)
    group by name, tag
) s
group by name
order by 1
;
 name |            tags             |  totals   
------+-----------------------------+-----------
 Bob  | {action,comedy,drama,sport} | {1,1,0,1}
 Sue  | {action,comedy,drama,sport} | {0,0,0,1}
 Tom  | {action,comedy,drama,sport} | {1,0,1,0}

Voor JSON-bewuste klanten een set JSON-objecten

select format(
    '{%s:{%s}}',
    to_json(name),
    string_agg(o, ',')
)::json as o
from (
    select name,
    format(
        '%s:%s',
        to_json(tag),
        to_json(count(a.name))
    ) as o
    from
        a
        right join (
            (select distinct tag from a) t
            cross join
            (select distinct name from a) n
        ) c using (name, tag)
    group by name, tag
) s
group by name
;
                          o                          
-----------------------------------------------------
 {"Bob":{"action":1,"comedy":1,"drama":0,"sport":1}}
 {"Sue":{"action":0,"comedy":0,"drama":0,"sport":1}}
 {"Tom":{"action":1,"comedy":0,"drama":1,"sport":0}}

of een enkel JSON-object

select format('{%s}', string_agg(o, ','))::json as o
from (
    select format(
        '%s:{%s}',
        to_json(name),
        string_agg(o, ',')
    ) as o
    from (
        select name,
        format(
            '%s:%s',
            to_json(tag),
            to_json(count(a.name))
        ) as o
        from
            a
            right join (
                (select distinct tag from a) t
                cross join
                (select distinct name from a) n
            ) c using (name, tag)
        group by name, tag
    ) s
    group by name
) s
;
                                                                            o                                                                            
---------------------------------------------------------------------------------------------------------------------------------------------------------
 {"Bob":{"action":1,"comedy":1,"drama":0,"sport":1},"Sue":{"action":0,"comedy":0,"drama":0,"sport":1},"Tom":{"action":1,"comedy":0,"drama":1,"sport":0}}



  1. Tabellen weergeven in MySQL en MariaDB

  2. Gematerialiseerde weergave in orakel met Fast Refresh in plaats van volledige dos werkt niet

  3. TO_CHAR van een Oracle PL/SQL TABLE-type

  4. MySQL 8 Het gemiddelde berekenen door te partitioneren op datum