消除满足条件的用户,即使他们可能不满足其他行中的条件

时间:2016-03-18 04:53:52

标签: mysql

我有一个查询(其中包括)寻找可以在某一天进行轮班的人。

invoices_list.sort(key=lambda i: DateKey(i))

为了解释结构,用户是用户主表,user_quals持有各种证书等(并且对于该用户可以是空的,或者具有许多条目),user_data为用户保存各种各样的信息。轮班保留班次日期和时间,地点等(也可能有很多或没有)。

我主要得到我想要的东西 - 具有属于特定组织(user_owner)的资格的活跃用户列表,其中user_level为Personnel,在该日期没有转变,但是如果他们被发现在另一个日期转移当然符合WHERE条款,他们就会出现。如果他们在那个日期有转变,即使它们可以在其他行中返回,我也不希望它们出现。

非常感谢任何指导。

2 个答案:

答案 0 :(得分:8)

您也可以在JOINshifts中解决此问题,将选择范围从表格缩小到仅限目标日期:

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

如果这不是你想要的结果,那么我误解了规范。示例数据和预期输出将有助于我理解规范。