我正在尝试重构我的一个查询,但我只是没有做正确的事情。
我想合并两个查询并创建一个,但我对它如何与 LEFT JOIN 一起工作感到困惑。
All QuizMasters who have a state of "active"
减号 (-)
QuizMasters who have an "active" event on a given day (not all QuizMasters have events only ~25%).
定义
- Events store
start_at
dow/wday for a given event, eg Monday-Sunday (albeit as a DateTime, only the wday and time are relevant).- Events and QuizMasters have states which are either "active" or not.
旧查询(哪些数据是正确的)
SELECT first_name, last_name, email
FROM quiz_masters
WHERE quiz_masters.state = 'active' # (175 rows)
EXCEPT
SELECT first_name, last_name, email
FROM quiz_masters
LEFT JOIN events ON events.quiz_master_id = quiz_masters.id
WHERE quiz_masters.state = 'active'
AND EXTRACT(dow FROM events.start_at::timestamp::date) = 3 AND events.state = 'active'
GROUP BY first_name, last_name, email # (- 20 rows)
共有 155 行匹配查询。
无效的组合查询
我想把它们组合成类似的东西:
SELECT first_name, last_name, email
FROM quiz_masters
LEFT JOIN events ON events.quiz_master_id = quiz_masters.id
WHERE quiz_masters.state = 'active'
AND events.quiz_master_id IS null
OR (EXTRACT(dow FROM events.start_at::timestamp::date) <> 3 AND events.state = 'active')
GROUP BY first_name, last_name, email
144行(少了11行)
但我不确定如何保留一些活跃但没有任何事件的 quiz_masters
的所有行。它仍然删除它们。也许我需要一些其他类型的加入?
最佳答案
在第一个查询中,您排除了周三的所有事件事件,因此包括了任何一天的非事件事件。在组合查询中,您包括除星期三以外的任何一天都活跃的所有事件,并且没有任何非活跃事件。那是你的 11 行差异。
这应该让你回到 155 行:
SELECT DISTINCT first_name, last_name, email
FROM quiz_masters
LEFT JOIN (
SELECT quiz_master_id AS id, state
FROM events
WHERE EXTRACT(dow FROM events.start_at::timestamp) = 3
AND events.state = 'active') ev USING (id)
WHERE quiz_masters.state = 'active'
AND ev.state IS NULL;
显然,您的测验大师有多个条目,但与其执行 GROUP BY
,不如选择 DISTINCT
行。 GROUP BY
只能与聚合函数一起使用。
关于sql - 重构 postgres join vs except,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39163040/