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

时间:2017-12-21 17:31:29

标签: sql postgresql

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

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。

此外,有时会在数据集中添加其他类别,并且我想知道是否可以在不事先了解所有可能的类别名称的情况下进行此查询,换句话说,我赢了&# 39;能够指定我想在结果中计算的所有列名。 (请注意,只有用户1具有类别" has_kids"并且用户3缺少类别"已婚"

(使用Postgres)

感谢。

3 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

select colpivot ('_pivoted', 'select * from user_categories', array['user_id'],
             array ['category'], '#.is_member',  null);

答案 2 :(得分: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作为默认值,将'|'替换为','作为分隔符。