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. Oracleの日付形式

    2. PostgreSQL-HTMLエンティティを置き換えます

    3. COALESCE 2つの日付はバイナリを返しますか?

    4. SQL結果をforeachループで使用する