我有一个查询(其中包括)寻找可以在某一天进行轮班的人。
invoices_list.sort(key=lambda i: DateKey(i))
为了解释结构,用户是用户主表,user_quals持有各种证书等(并且对于该用户可以是空的,或者具有许多条目),user_data为用户保存各种各样的信息。轮班保留班次日期和时间,地点等(也可能有很多或没有)。
我主要得到我想要的东西 - 具有属于特定组织(user_owner)的资格的活跃用户列表,其中user_level为Personnel,在该日期没有转变,但是如果他们被发现在另一个日期转移当然符合WHERE条款,他们就会出现。如果他们在那个日期有转变,即使它们可以在其他行中返回,我也不希望它们出现。
非常感谢任何指导。
答案 0 :(得分:8)
您也可以在JOIN
至shifts
中解决此问题,将选择范围从表格缩小到仅限目标日期:
LEFT OUTER JOIN shifts ON shifts.shift_user = users.user_id and date(shifts.shift_start)='2016-03-16'
然后在WHERE
子句中,仅定位null
的{{1}}条记录:
shift_start
或
WHERE shift_start IS NULL
答案 1 :(得分:1)
你不清楚自己需要完成什么。示例数据和示例输出将大大有助于清除它。设置SQLfiddle http://sqlfiddle.com可能会帮助您更快地得到答案。
我怀疑问题出在WHERE
子句中的shift_date谓词。
听起来你所追求的结果可能是由一个"反连接"图案。从外部联接开始,在这种情况下,返回users
中的所有行以及来自shifts
的匹配行。
SELECT u.user_id
FROM users u
LEFT
JOIN shifts s
ON s.user_id = u.user_id
在这种情况下,您希望找到从给定日期开始的匹配班次...
AND s.shift_start >= '2016-03-16'
AND s.shift_start < '2016-03-16' + INTERVAL 1 DAY
&#34;但是等等,你说,&#34;那些是我不想要的行。&#34;
右。
但它是外部联接,因此我们从users
获取所有行。如果shifts
中有任何匹配的行,我们也会得到这些行。对于users
中不具有匹配行(符合ON
子句中指定条件)的任何行,{{1}列中的列值将为NULL。
诀窍是排除匹配的行。 shifts
中的任何实际行都会在shifts
中包含非空值。 (我们保证,由于shift_start
子句中的条件,ON
的NULL值不满足条件。)因此,我们只想返回行shift_start
的NULL值。使用该条件添加WHERE子句非常简单:
shift_start
任何具有匹配行的用户都将不返回。所以我们得到的只是不在指定日期开始转换的用户。
把所有这些放在一起:
WHERE s.shift_start IS NULL
显然,这并不是唯一会返回该结果的查询模式。我们可以使用带有SELECT u.user_id
FROM users u
LEFT
JOIN shifts s
ON s.user_id = u.user_id
AND s.shift_start >= '2016-03-16'
AND s.shift_start < '2016-03-16' + INTERVAL 1 DAY
WHERE s.shift_start IS NULL
谓词的查询来获得等效结果。
反连接模式有点让你的大脑缠绕。但是一旦掌握了它,它就是保存在SQL工具带中的强大工具。
为了清楚起见,我省略了其他表格。我希望您能够填写选择列表,添加连接到其他表,添加NOT EXISTS
等等,以构建您需要的实际集合。
GROUP BY
如果这不是你想要的结果,那么我误解了规范。示例数据和预期输出将有助于我理解规范。