【发布时间】:2021-08-24 22:13:53
【问题描述】:
【问题讨论】:
-
您附上图片了吗?如果是这样,它不会显示。
标签: sql postgresql pivot
【问题讨论】:
标签: sql postgresql pivot
您可以使用bool_or() 聚合函数来实现:
select movie,
bool_or(genre = 'Action') as is_action,
bool_or(genre = 'Fantasy') as is_fantasy,
bool_or(genre = 'Crime') as is_crime,
bool_or(genre = 'Comedy') as is_comedy
from the_table
group by movie
请注意,这将返回一个真正的boolean 值,而不是0 或1,我发现这样的“标志”列更符合逻辑。如果您确实更喜欢整数而不是布尔值作为真/假标志,只需将函数的结果转换为 int,例如bool_or(....)::int
【讨论】:
这是一种蛮力的方法。如果你有很多流派,它可能会变得乏味。
首先创建表并插入数据。出于说明目的,我制作了另一部电影:
CREATE TABLE t1 (movie text, genre text);
INSERT INTO t1 (movie, genre)
VALUES ('ABC', 'Action'),
('ABC', 'Fantasy'),
('DEF', 'Comedy'),
('DEF', 'Action');
要获得您想要的列,首先您可以为每个类型的电影创建一行:
SELECT movie,
CASE WHEN genre = 'Action' THEN 1 ELSE 0 END AS isAction,
CASE WHEN genre = 'Fantasy' THEN 1 ELSE 0 END AS isFantasy,
CASE WHEN genre = 'Comedy' THEN 1 ELSE 0 END AS isComedy,
CASE WHEN genre = 'Crime' THEN 1 ELSE 0 END AS isCrime
FROM t1
这给出了太多的行
| movie | isaction | isfantasy | iscomedy | iscrime |
|---|---|---|---|---|
| ABC | 1 | 0 | 0 | 0 |
| ABC | 0 | 1 | 0 | 0 |
| DEF | 0 | 0 | 1 | 0 |
| DEF | 1 | 0 | 0 | 0 |
但我们可以通过求和和 GROUP BY 类型来减少行数
WITH t2 as (
SELECT movie,
CASE WHEN genre = 'Action' THEN 1 ELSE 0 END AS isAction,
CASE WHEN genre = 'Fantasy' THEN 1 ELSE 0 END AS isFantasy,
CASE WHEN genre = 'Comedy' THEN 1 ELSE 0 END AS isComedy,
CASE WHEN genre = 'Crime' THEN 1 ELSE 0 END AS isCrime
FROM t1)
SELECT movie, sum(isAction) as isAction,
sum(isFantasy) as isFantasy,
sum(isComedy) as isComedy,
sum(isCrime) as isCrime
FROM t2
GROUP BY movie
给了
| movie | isaction | isfantasy | iscomedy | iscrime |
|---|---|---|---|---|
| ABC | 1 | 1 | 0 | 0 |
| DEF | 1 | 0 | 1 | 0 |
现在讨论数据类型并将这些数据放入表中。正如所写,这些查询将具有 isAction 等列作为 bigint。您实际上可能需要布尔值,在这种情况下,您必须先转换为 int,然后再转换为布尔值(例如 sum(isAction)::int::bool as isAction...)。
要将数据放入表中,请将最后一个 SELECT 查询替换为 SELECT INTO 查询,这将自动为您创建一个新表。
【讨论】: