如果列值未知,则SQL将行转换为列

问题描述 投票:1回答:3

我有一个表,其中包含有关一组用户的人口统计信息,如下所示:

User_id   Category IsMember
1         College     1
1         Married     0
1         Employed    1
1         Has_Kids    1
2         College     0
2         Married     1
2         Employed    1
3         College     0
3         Employed    0

我想要的结果集是一个如下所示的表:

User_Id|College|Married|Employed|Has_Kids
1            1        0        1        1
2            0        1        1        0
3            0        0        0        0

换句话说,该表指示每个用户是否存在类别。有时用户会有一个类别,其中值为false,有时用户将没有类别的行,在这种情况下,IsMember被假定为false。

此外,有时会在数据集中添加其他类别,我想知道是否可以在不事先知道所有可能的类别名称的情况下进行此查询,换句话说,我将无法指定我想在结果中计算的所有列名。 (注意只有用户1有类别“has_kids”而用户3缺少类别“已婚”的行

(使用Postgres)

谢谢。

sql postgresql
3个回答
0
投票

您可以使用jsonb函数。

with titles as (
 select jsonb_object_agg(Category, Category) as titles,
        jsonb_object_agg(Category, -1) as defaults
   from demog
),
the_rows as (
select null::bigint as id, titles as data
  from titles
union
select User_id, defaults || jsonb_object_agg(Category, IsMember)
  from demog, titles
  group by User_id, defaults
)
select id, string_agg(value, '|' order by key)
  from (
    select id, key, value
      from the_rows, jsonb_each_text(data)
  ) x
  group by id
  order by id nulls first

您可以在http://rextester.com/QEGT70842中看到一个正在运行的示例

您可以使用-1替换0作为默认值,使用'|'替换','作为分隔符。


0
投票

您可以安装tablefunc模块并使用交叉表功能。

https://www.postgresql.org/docs/9.1/static/tablefunc.html


0
投票

我发现了一个名为colpivot here的Postgres函数脚本。运行脚本来创建函数,然后在一个语句中创建表:

select colpivot ('_pivoted', 'select * from user_categories', array['user_id'],
             array ['category'], '#.is_member',  null);
© www.soinside.com 2019 - 2024. All rights reserved.