【问题标题】:How do you convert rows to columns in Postgres?如何在 Postgres 中将行转换为列?
【发布时间】:2021-04-20 07:38:26
【问题描述】:

我有一个包含以下列的表格:user_id、grade。

user_id | grade
1         k
1         3
2         4
2         5
3         2

我希望能够制作一个看起来像user_id、grade_k、grade_1 等的表格,如果用户教那个等级,每个等级都有一个对或错。

您似乎可以使用 crosstab 来执行此操作,但有人可以给我举个例子吗?

期望的输出:

user_id | grade_k | grade_1 | grade_2 | grade_3 | grade_4 | grade_5
1         1         0         0         1         0         0
2         0         0         0         0         1         1
3         0         0         1         0         0         0

我想这样做的原因是,这种格式将使在数据可视化工具中进行过滤变得更加容易。

【问题讨论】:

  • 请为给定的示例数据输入所需的结果。我也很好奇教授 X 级的用户是否也能教授低于 X 的年级,期望的结果将有助于回答
  • 可以添加所需的输出吗?

标签: sql postgresql pivot


【解决方案1】:

使用过滤聚合通常比使用crosstab() 函数容易得多:

select user_id, 
       max(grade) filter(where grade = 'k') is not null as teaches_grade_k,
       max(grade) filter(where grade = '1') is not null as teaches_grade_1,
       max(grade) filter(where grade = '2') is not null as teaches_grade_2,
       max(grade) filter(where grade = '3') is not null as teaches_grade_3,
       max(grade) filter(where grade = '4') is not null as teaches_grade_5
       max(grade) filter(where grade = '5') is not null as teaches_grade_5
from users
group by user_id;       

【讨论】:

    【解决方案2】:

    另一个类似于过滤聚合的选项是使用常规数组聚合并检查是否存在,例如

    WITH users (user_id, grade) AS (
        VALUES
            (1, 'k'),
            (1, '1'),
            (2, '4'),
            (2, '5'),
            (3, '2')
    ),
    user_grades AS (
        SELECT user_id, array_agg(grade) AS grades
        FROM users
        GROUP BY user_id
    )
    SELECT
        user_id,
        'k' = ANY(grades) AS teaches_k,
        '1' = ANY(grades) AS teaches_1,
        '2' = ANY(grades) AS teaches_2,
        '3' = ANY(grades) AS teaches_3,
        '4' = ANY(grades) AS teaches_4,
        '5' = ANY(grades) AS teaches_5
    FROM
        user_grades
    

    【讨论】:

      猜你喜欢
      • 2021-12-03
      • 1970-01-01
      • 2021-11-15
      • 2016-10-06
      • 2021-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多