【问题标题】:POSTGRESQL-Converting multiple rows with different values to columns to one row and different columnsPOSTGRESQL-将多行不同值的列转换为一行不同的列
【发布时间】:2021-08-24 22:13:53
【问题描述】:

您好 作为 POSTGRESQL 的新手,我需要将多行数据转换为一行多列。如何在 POSTGRESQL 中做到这一点。 我想转换下面的数据

【问题讨论】:

  • 您附上图片了吗?如果是这样,它不会显示。

标签: sql postgresql pivot


【解决方案1】:

您可以使用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

【讨论】:

  • 不错。我不知道这个功能。
【解决方案2】:

这是一种蛮力的方法。如果你有很多流派,它可能会变得乏味。

首先创建表并插入数据。出于说明目的,我制作了另一部电影:

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 查询,这将自动为您创建一个新表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2020-11-16
    • 2021-06-18
    • 1970-01-01
    相关资源
    最近更新 更多