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')
;
La requête pour le chat :
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
Si le nombre de votants est important ou inconnu, cela peut être fait dynamiquement :
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$;
Le code ci-dessus a créé le tableau croisé dynamique avec toutes les décisions :
select * from pivot where decision = 'Cat';