[英]Get Row Totals for Dynamically Created Pivoted Table
在 PostgreSQL 中,我有一个这样的表:
CREATE TABLE cross_table (brand varchar(10), gender varchar(10), sales int);
INSERT INTO cross_table (brand, gender, sales) VALUES ('Nike', 'Male', 10);
INSERT INTO cross_table (brand, gender, sales) VALUES ('Nike', 'Male', 20);
INSERT INTO cross_table (brand, gender, sales) VALUES ('Adidas', 'Woman', 20);
INSERT INTO cross_table (brand, gender, sales) VALUES ('Nike', 'Male', 10);
INSERT INTO cross_table (brand, gender, sales) VALUES ('Adidas', 'Woman', 30);
INSERT INTO cross_table (brand, gender, sales) VALUES ('Puma', 'Woman', 40);
INSERT INTO cross_table (brand, gender, sales) VALUES ('Puma', 'Male', 10);
INSERT INTO cross_table (brand, gender, sales) VALUES ('Nike', 'Male', 20);
INSERT INTO cross_table (brand, gender, sales) VALUES ('Puma', 'Woman', 10);
INSERT INTO cross_table (brand, gender, sales) VALUES ('Adidas', 'Woman', 20);
然后我运行此查询以将品牌作为行,将性别作为列并将销售额作为值:
with main_query as (
SELECT brand,
GROUPING(brand) AS "brand_grouping",
gender,
GROUPING(gender) AS "gender_grouping",
sum(sales) AS "sales"
FROM cross_table
GROUP BY ROLLUP (brand, gender)
),
second_query AS (
SELECT brand,
brand_grouping,
cast(
json_object_agg(
gender,
sales
ORDER BY gender DESC
) FILTER (WHERE gender_grouping = 0) AS jsonb) "gender",
SUM(sales) AS "sales"
FROM main_query
GROUP BY (brand, brand_grouping)
)
SELECT brand,
gender,
sales
FROM second_query
ORDER BY brand_grouping, brand
这将产生以下结果:
品牌 | 性别 | 销售量 |
---|---|---|
阿迪达斯 | { “女人”:70 } | 140 |
耐克 | “男”:60 | 120 |
彪马 | “男”:10,“女”:50 | 120 |
NULL | NULL | 190 |
请注意:性别列现在位于 object 中,但括号不会显示在 Stackoverflow 上的表格视图中。
这很好,唯一的问题是它缺少透视“性别”列的行总计。 我可以通过将最后一个查询更改为此来解决这个硬编码:
SELECT brand,
CASE WHEN gender IS null THEN
jsonb_build_object(
'Woman', SUM(("gender"->>'Woman')::float8) OVER (),
'Male', SUM(("gender"->>'Male')::float8) OVER ()
) ELSE "gender" END AS "gender",
sales
FROM second_query
ORDER BY brand_grouping, brand
得到这个结果:
品牌 | 性别 | 销售量 |
---|---|---|
阿迪达斯 | {“女人”:70} | 140 |
耐克 | “男”:60 | 120 |
彪马 | “男”:10,“女”:50 | 120 |
NULL | “男”:70,“女”:120 | 190 |
这是正确的,但我需要在不知道“性别”的键(男/女)的情况下动态地执行此操作。
有谁知道如何做到这一点?
尝试这个:
SELECT brand
, jsonb_object_agg(gender, sales) AS gender
, sum(sales) AS sales
FROM (
SELECT brand
, gender
, sum(sales) AS sales
FROM cross_table
GROUP BY ROLLUP(brand), gender
) AS a
GROUP BY brand
结果:
品牌 | 性别 | 销售量 |
---|---|---|
null | {“男”:70,“女”:120} | 190 |
阿迪达斯 | {“女人”:70} | 70 |
耐克 | {“男”:60} | 60 |
彪马 | {“男”:10,“女”:50} | 60 |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.