Su primer error parece ser simple. Según el segundo parámetro de crosstab()
función, 'Dubai'
debe venir como primera ciudad (ordenada por ciudad). Detalles:
Los valores inesperados para totalsales
y totalamount
representar valores de la primera fila para cada name
grupo. Las columnas "extra" se tratan así. Detalles:
Para obtener sumas por name
, ejecute funciones de ventana sobre sus funciones agregadas. Detalles:
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
);
Mejor aún, proporcione un conjunto estático como segundo parámetro. Las columnas de salida están codificadas de forma rígida, puede que no sea fiable generar columnas de datos de forma dinámica. Si colocas otra fila con una nueva ciudad, esta se rompería.
De esta manera también puedes ordenar tus columnas como quieras. Simplemente mantenga sincronizadas las columnas de salida y el segundo parámetro.