あなたの最初の間違いは単純なようです。 crosstab()
の2番目のパラメータによると 関数、'Dubai'
最初の都市として来る必要があります(都市でソート)。詳細:
totalsales
の予期しない値 およびtotalamount
各name
の最初の行の値を表します グループ。 「余分な」列はそのように扱われます。詳細:
name
ごとの合計を取得するには 、集計関数に対してウィンドウ関数を実行します。詳細:
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
);
さらに良いことに、2番目のパラメーターとして静的セットを提供します。出力列はハードコーディングされているため、データ列を動的に生成することは信頼できない場合があります。新しい都市の別の行の場合、これは壊れます。
このようにして、好きなように列を並べ替えることもできます。出力列と2番目のパラメータの同期を維持するだけです。