使用CASE WHEN从单独的行中获取单独的值

时间:2017-07-14 22:33:52

标签: sql postgresql pivot case-when

我有一个数据集,其中用户有2个操作,一个有用的操作和一个无用的操作:

user_id | action_id | useful
   1    |     3     |  True
   1    |     4     |  False
   2    |     5     |  True

我想要一个显示用户ID的数据集,以及他们在同一行上执行的有用和无用操作的ID。像这样:

user_id | useful_action_id | not_useful_action_id
   1    |       3          |         4
   2    |       5          |       NULL

我尝试了以下内容:

SELECT
    user_id,
    case when useful = True then action_id else null end,
    case when useful = False then action_id else null end
FROM actions
GROUP BY user_id

但我被告知:

Error running query: column "useful" must appear in the `GROUP BY` clause or be used in an aggregate function

但不,我特别不希望'有用'出现在GROUP BY对吗?我只是希望按user_id

分组

2 个答案:

答案 0 :(得分:2)

您正在使用GROUP BY,但不执行聚合。看起来你正在尝试条件聚合而且你非常接近。您只需使用聚合函数,如下所示:

SELECT
    user_id,
    max(case when useful = True then action_id end) AS useful_action_id,
    max(case when useful = False then action_id end) AS not_useful_action_id
FROM actions
GROUP BY user_id

答案 1 :(得分:1)

如果你想拥有"有用"并且"无用"每个用户的ID,使用a/b/c聚合函数:

array_agg()

其他一些评论:

  • 如果在组中找不到ID,它将输出空数组(select user_id, array_agg(action_id) filter (where useful) as useful_action_ids, array_agg(action_id) filter (where not useful) as not_useful_action_ids from actions group by 1; ),而不是NULL。如果确实需要NULL,请添加case / when表达式。
  • 如果{}列中有NULL,则上述查询不会使用它们。在这种情况下,如果您确实希望将这些NULL视为"无效",请使用useful。但是,您可能更愿意再使用一组ID,例如(where not coalesce(useful, false))usefulness_is_not_clear :)