Votre première erreur semble être simple. Selon le 2ème paramètre du crosstab()
fonction, 'Dubai'
doit venir en premier lieu (trié par ville). Détails :
Les valeurs inattendues pour totalsales
et totalamount
représentent les valeurs de la première ligne pour chaque name
groupe. Les colonnes "Extra" sont traitées comme ça. Détails :
Pour obtenir des sommes par name
, exécutez les fonctions de fenêtre sur vos fonctions d'agrégation. Détails :
select * from crosstab (
'select name
,sum(count(*)) OVER (PARTITION BY name)
,sum(sum(price)) OVER (PARTITION BY name)
,city
,count(city)
from products
group by name,city
order by name,city
'
-- ,'select distinct city from products order by 1' -- replaced
,$$SELECT unnest('{Dubai,London,Melborun
,Moscow,Munich,Shunghai}'::varchar[])$$
) AS tb (
name varchar(20), TotalSales bigint, TotalAmount bigint
,Dubai bigint
,London bigint
,Melborun bigint
,Moscow bigint
,Munich bigint
,Shunghai bigint
);
Mieux encore, fournissez un ensemble statique comme 2ème paramètre. Les colonnes de sortie sont codées en dur, il peut être peu fiable de générer dynamiquement des colonnes de données. Si vous avez une autre ligne avec une nouvelle ville, cela cassera.
De cette façon, vous pouvez également ordonner vos colonnes comme vous le souhaitez. Gardez simplement les colonnes de sortie et le 2e paramètre synchronisés.