我尝试通过对几列进行分组来创建数据透视表:用户 ID、姓名、周数和日期名称。 当前的请求没有给出期望的结果。 我需要帮助。
这是我的桌子:
user_id name week_number day_name price
2 Luc 8 Sunday 10
2 Luc 8 Monday 15
2 Luc 8 Tuesday 8
2 Luc 8 Wednesday 2
2 Luc 8 Thursday 9
2 Luc 8 Friday 9
2 Luc 8 Saturday 11
2 Luc 9 Saturday 1
2 Luc 9 Friday 13
3 Mathieu 8 Sunday 22
3 Mathieu 8 Monday 13
3 Mathieu 8 Tuesday 9
3 Mathieu 8 Wednesday 3
这是我当前的要求:
SELECT *
FROM crosstab(
'SELECT user_id, name, week_number,day_name,price
FROM table_1
ORDER BY 1,2,3,4'
) AS ct (
"user_id" integer,
"day_name" text,
"Sunday" integer,
"Monday" integer,
"Tuesday" integer,
"Wednesday" integer,
"Thursday" integer,
"Friday" integer,
"Saturday" integer
);
这是我想要得到的结果。
您可以只使用条件聚合:
SELECT user_id, name, week_number
MAX(price) FILTER (WHERE day_name = 'Sunday') as Sunday,
MAX(price) FILTER (WHERE day_name = 'Monday') as Monday,
MAX(price) FILTER (WHERE day_name = 'Tuesday') as Tuesday,
MAX(price) FILTER (WHERE day_name = 'Wednesday') as Wednesday,
MAX(price) FILTER (WHERE day_name = 'Thursday') as Thursday,
MAX(price) FILTER (WHERE day_name = 'Friday') as Friday,
MAX(price) FILTER (WHERE day_name = 'Saturday') as Saturday
FROM table_1
GROUP BY user_id, name, week_number
ORDER BY user_id, name, week_number;
编辑:
你可以在没有
FILTER
的情况下编写相同的逻辑:
MAX(CASE WHEN day_name = 'Sunday' THEN price END) as Sunday,
下面的 SQL 使用
crosstab
函数,仅使用额外的列 uniuq_id
即可给出预期结果。
SELECT *
FROM crosstab(
'SELECT CONCAT(user_id,name,week_number) as unique_id,
user_id,name,week_number,day_name,price
FROM table_1
ORDER BY unique_id',
'SELECT day_name FROM (VALUES (''Monday''), (''Tuesday''),
(''Wednesday''), (''Thursday''), (''Friday''),
(''Saturday''), (''Sunday'')) b(day_name)'
) AS ct (
"unique_id" varchar,
"user_id" integer,
"name" varchar,
"week_number" integer,
"Monday" integer,
"Tuesday" integer,
"Wednesday" integer,
"Thursday" integer,
"Friday" integer,
"Saturday" integer,
"Sunday" integer
);
解释
crosstab
函数有3组参数
在问题中,您实际上使用的是第一个
crosstab
,并且它期望 sql text
仅返回具有特定含义的 3 列:
row_name cat value
----------+-------+-------
row1 cat1 val1
row1 cat2 val2
row2 cat1 val3
并且
crosstab
将上面的表格旋转为下面的格式:
row_name cat1 cat2
----------+-------+-------
row1 val1 val2
row2 val3 null
问题中的 SQL 返回 5 列,这会导致语法错误。
在这种情况下,我们需要使用
crosstab
的第二种形式:
crosstab(source_sql, category_sql)
source_sql
仅遵循以下规则即可返回 3 列以上:
为了组成这样的
source_sql
,请使用以下语句:
SELECT CONCAT(user_id,name,week_number) as unique_id,
user_id,name,week_number,day_name,price
FROM table_1
ORDER BY unique_id
category_sql
返回我们期望转换为列的值,下面的语句仅按预期顺序返回工作日。
SELECT day_name FROM (VALUES ('Monday'), ('Tuesday'), ('Wednesday'), ('Thursday'), ('Friday'), ('Saturday'), ('Sunday')) b(day_name)
总而言之,我们首先得到了完整的 SQL。