PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

завъртане/кръстосване на данни от различни редове към колони с postgres

Някои прости решения, подходящи за някои случаи. Използване на тази таблица (SQL Fiddle не работи в момента)

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');

Просто агрегиране на масиви, ако те могат да бъдат разделени някъде другаде

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}

За клиенти, които познават JSON, набор от JSON обекти

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}}

или един JSON обект

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. За да конвертирате бързо от Python масиви в PostgreSQL?

  2. Персонализиран номер на седмицата на PostgreSQL - първата седмица, съдържаща 1 февруари

  3. Връща име на колона и отделни стойности

  4. Потребител на Postgres създава база данни

  5. Postgres избира текущи данни за час