Seu primeiro erro parece ser simples. De acordo com o 2º parâmetro do
crosstab()
função, 'Dubai'
deve vir como primeira cidade (classificada por cidade). Detalhes:Os valores inesperados para
totalsales
e totalamount
representam valores da primeira linha para cada name
grupo. As colunas "extras" são tratadas assim. Detalhes:Para obter somas por
name
, execute funções de janela sobre suas funções agregadas. Detalhes: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
);
Melhor ainda, forneça um conjunto estático como 2º parâmetro. As colunas de saída são codificadas, pode não ser confiável gerar colunas de dados dinamicamente. Se você tiver outra linha com uma nova cidade, isso quebrará.
Dessa forma, você também pode ordenar suas colunas como quiser. Apenas mantenha as colunas de saída e o segundo parâmetro sincronizados.