我有以下查询,它基本上告诉我与他所做的考试相关的用户的状态:
SELECT users.id,
CASE WHEN users.closed_at IS NOT NULL
THEN 'closed'
WHEN COUNT(exams.id) FILTER(users.closed_at IS NOT NULL OR requests.finished_at IS NOT NULL) = COUNT(exams.id)
THEN 'completed'
WHEN COUNT(exams.id) FILTER(users.closed_at IS NOT NULL OR requests.finished_at IS NOT NULL) = 0
then 'not-completed'
ELSE 'in-progress'
END AS user_status
LEFT JOIN exams ON exams.user_id = users.id
这很好用,但现在我也希望能够根据用户的考试状态进行过滤,同时考虑到我应该能够按多种状态进行过滤。我被建议用子查询做这个,所以假设我想找到考试状态已关闭或“未完成”的用户,我试过这个:
SELECT users.id,
CASE WHEN users.closed_at IS NOT NULL
THEN 'closed'
WHEN COUNT(exams.id) FILTER(users.closed_at IS NOT NULL OR requests.finished_at IS NOT NULL) = COUNT(exams.id)
THEN 'completed'
WHEN COUNT(exams.id) FILTER(users.closed_at IS NOT NULL OR requests.finished_at IS NOT NULL) = 0
then 'not-completed'
ELSE 'in-progress'
END AS user_status
LEFT JOIN exams ON exams.user_id = users.id
WHERE (
SELECT
CASE WHEN users.closed_at IS NOT NULL
THEN 'closed'
WHEN COUNT(exams.id) FILTER(users.closed_at IS NOT NULL OR requests.finished_at IS NOT NULL) = COUNT(exams.id)
THEN 'completed'
WHEN COUNT(exams.id) FILTER(users.closed_at IS NOT NULL OR requests.finished_at IS NOT NULL) = 0
then 'not-completed'
ELSE 'in-progress'
END AS user_status_in_inner_query
) user_status_in_inner_query = 'closed' OR user_status_in_inner_query = 'not-completed'
但它抛出一个错误,说“在WHERE中不允许聚合函数”。我怎么能这样做?
答案 0 :(得分:1)
我希望这样的东西能起作用吗?
SELECT id, user_status
FROM (
SELECT users.id,
CASE WHEN users.closed_at IS NOT NULL
THEN 'closed'
WHEN COUNT(exams.id) FILTER(users.closed_at IS NOT NULL OR requests.finished_at IS NOT NULL) = COUNT(exams.id)
THEN 'completed'
WHEN COUNT(exams.id) FILTER(users.closed_at IS NOT NULL OR requests.finished_at IS NOT NULL) = 0
then 'not-completed'
ELSE 'in-progress'
END AS user_status
LEFT JOIN exams ON exams.user_id = users.id
) xx
WHERE user_status IN ('closed', 'not-completed')
基本上只需将原始查询作为子查询,并使用您想要的任何过滤器对其进行标准选择。
答案 1 :(得分:1)
不要在WHERE
子句中重复查询,将所有内容放入派生表中,然后可以使用别名:
select *
from (
SELECT users.id,
CASE
WHEN users.closed_at IS NOT NULL THEN 'closed'
WHEN COUNT(exams.id) FILTER(users.closed_at IS NOT NULL OR requests.finished_at IS NOT NULL) = COUNT(exams.id)
THEN 'completed'
WHEN COUNT(exams.id) FILTER(users.closed_at IS NOT NULL OR requests.finished_at IS NOT NULL) = 0
then 'not-completed'
ELSE 'in-progress'
END AS user_status
FROM users --<<< Seems to be missing in your query
LEFT JOIN exams ON exams.user_id = users.id
) t
where user_status in ('closed', 'not-completed');