sql >> データベース >  >> RDS >> PostgreSQL

多数または未定義のカテゴリとのクロス集計

    create table vote (Photo integer, Voter text, Decision text);
    insert into vote values
    (1, 'Alex', 'Cat'),
    (1, 'Bob', 'Dog'),
    (1, 'Carol', 'Cat'),
    (1, 'Dave', 'Cat'),
    (1, 'Ed', 'Cat'),
    (2, 'Alex', 'Cat'),
    (2, 'Bob', 'Dog'),
    (2, 'Carol', 'Cat'),
    (2, 'Dave', 'Cat'),
    (2, 'Ed', 'Dog'),
    (3, 'Alex', 'Horse'),
    (3, 'Bob', 'Horse'),
    (3, 'Carol', 'Dog'),
    (3, 'Dave', 'Horse'),
    (3, 'Ed', 'Horse'),
    (4, 'Alex', 'Horse'),
    (4, 'Bob', 'Horse'),
    (4, 'Carol', 'Cat'),
    (4, 'Dave', 'Horse'),
    (4, 'Ed', 'Horse'),
    (5, 'Alex', 'Dog'),
    (5, 'Bob', 'Cat'),
    (5, 'Carol', 'Cat'),
    (5, 'Dave', 'Cat'),
    (5, 'Ed', 'Cat')
    ;
    

    猫のクエリ:

    select photo,
        alex + bob + carol + dave + ed as Total,
        alex, bob, carol, dave, ed
    from crosstab($$
        select
            photo, voter,
            case decision when 'Cat' then 1 else 0 end
        from vote
        order by photo
        $$,'
        select distinct voter
        from vote
        order by voter
        '
    ) as (
        photo integer,
        Alex integer,
        Bob integer,
        Carol integer,
        Dave integer,
        Ed integer
    );
     photo | total | alex | bob | carol | dave | ed 
    -------+-------+------+-----+-------+------+----
         1 |     4 |    1 |   0 |     1 |    1 |  1
         2 |     3 |    1 |   0 |     1 |    1 |  0
         3 |     0 |    0 |   0 |     0 |    0 |  0
         4 |     1 |    0 |   0 |     1 |    0 |  0
         5 |     4 |    0 |   1 |     1 |    1 |  1
    

    有権者の数が多いか不明な場合は、動的に行うことができます。

    do $do$
    declare
    voter_list text;
    r record;
    begin
    
    drop table if exists pivot;
    
    voter_list := (
        select string_agg(distinct voter, ' ' order by voter) from vote
        );
    
    execute(format('
        create table pivot (
            decision text,
            photo integer,
            Total integer,
            %1$s
        )', (replace(voter_list, ' ', ' integer, ') || ' integer')
    ));
    
    for r in
    select distinct decision from vote
    loop
        execute (format($f$
            insert into pivot
            select
                %3$L as decision,
                photo,
                %1$s as Total,
                %2$s
            from crosstab($ct$
                select
                    photo, voter,
                    case decision when %3$L then 1 else 0 end
                from vote
                order by photo
                $ct$,$ct$
                select distinct voter
                from vote
                order by voter
                $ct$
            ) as (
                photo integer,
                %4$s
            );$f$,
            replace(voter_list, ' ', ' + '),
            replace(voter_list, ' ', ', '),
            r.decision,
            replace(voter_list, ' ', ' integer, ') || ' integer'
        ));
    end loop;
    end; $do$;
    

    上記のコードは、すべての決定を含むテーブルピボットを作成しました:

    select * from pivot where decision = 'Cat';
    


    1. MariaDB Enterpriseとは何ですか?ClusterControlで管理する方法は?

    2. MySQLとNoSQL:適切なものを選択するのを手伝ってください

    3. rownumの使用方法

    4. 「それは秘密ですか?安全ですか?」データモデリングでの機密データの処理