使用 CASE WHEN 从不同的行获取不同的值
Getting separate values from separate rows using 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
但是不,我特别不希望 'useful' 出现在 GROUP BY
中,对吗?我只想将它按 user_id
分组
您正在使用 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
如果您希望每个用户都有 "useful" 和 "not useful" ID,请使用 array_agg()
聚合函数:
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;
一些补充意见:
- 如果在组中没有找到ID,它将输出空数组(
{}
),而不是NULL。如果确实需要 NULL,请添加 case/when 表达式。
- 如果
useful
列中有 NULL,上面的查询将不会采用它们。在这种情况下,如果您确实希望将此类 NULL 视为 "not useful",只需使用 (where not coalesce(useful, false))
。但是您可能更喜欢多一组 ID,例如 usefulness_is_not_clear
和 filter (where useful is null)
:)
我有一个数据集,其中用户有 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
但是不,我特别不希望 'useful' 出现在 GROUP BY
中,对吗?我只想将它按 user_id
您正在使用 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
如果您希望每个用户都有 "useful" 和 "not useful" ID,请使用 array_agg()
聚合函数:
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;
一些补充意见:
- 如果在组中没有找到ID,它将输出空数组(
{}
),而不是NULL。如果确实需要 NULL,请添加 case/when 表达式。 - 如果
useful
列中有 NULL,上面的查询将不会采用它们。在这种情况下,如果您确实希望将此类 NULL 视为 "not useful",只需使用(where not coalesce(useful, false))
。但是您可能更喜欢多一组 ID,例如usefulness_is_not_clear
和filter (where useful is null)
:)