Ditt första misstag verkar vara enkelt. Enligt den andra parametern i crosstab()
funktion, 'Dubai'
måste komma som första stad (sorterad efter stad). Detaljer:
De oväntade värdena för totalsales
och totalamount
representerar värden från den första raden för varje name
grupp. "Extra" kolumner behandlas så. Detaljer:
För att få summor per name
, kör fönsterfunktioner över dina aggregerade funktioner. Detaljer:
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
);
Ännu bättre, tillhandahåll en statisk uppsättning som andra parameter. Utdatakolumner är hårdkodade, det kan vara opålitligt att generera datakolumner dynamiskt. Om du en annan rad med en ny stad, skulle detta gå sönder.
På detta sätt kan du också beställa dina kolumner som du vill. Håll bara utdatakolumner och den andra parametern synkroniserade.