Ihr erster Fehler scheint einfach zu sein. Gemäß dem 2. Parameter der crosstab()
Funktion, 'Dubai'
muss als erste Stadt kommen (sortiert nach Stadt). Einzelheiten:
Die unerwarteten Werte für totalsales
und totalamount
stellen Werte aus der ersten Zeile für jeden name
dar Gruppe. "Zusätzliche" Spalten werden so behandelt. Einzelheiten:
Um Summen pro name
zu erhalten , führen Sie Fensterfunktionen über Ihre Aggregatfunktionen aus. Einzelheiten:
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
);
Besser noch, geben Sie einen statischen Satz als 2. Parameter an. Ausgabespalten sind fest codiert, es kann unzuverlässig sein, Datenspalten dynamisch zu generieren. Wenn Sie eine weitere Zeile mit einer neuen Stadt hinzufügen, würde diese brechen.
So können Sie Ihre Spalten auch nach Belieben anordnen. Halten Sie einfach die Ausgabespalten und den zweiten Parameter synchron.