MYSQL通过where子句排除匹配值

时间:2019-06-24 15:30:19

标签: mysql

我对基本查询感到困惑,我有2个表employeesemployee_time_off。我想提取所有在特定日期没有下班的员工。

我尝试过的是

SELECT
    employees.id,
    employees.FIRST_NAME
FROM `employees`
LEFT JOIN `employee_time_off` ON `employees`.`id` = `employee_time_off`.`employee_id` 
    AND `START_DATE` < '2019-06-30 00:00:00' AND `END_DATE` > '2019-06-30 12:59:59' 

START_DATE实际上是叶子开始的时刻,END_DATE是叶子结束的时候。

因此,在这种情况下,具有id=1的员工不应出现在结果集中。但是结果集使所有雇员从1增至6。

employees

employee_time_off

3 个答案:

答案 0 :(得分:1)

NOT EXISTS怎么样?

SELECT e.*
FROM employees e
WHERE NOT EXISTS (SELECT 1
                  FROM employee_time_off eto
                  WHERE eto.employee_id = e.id AND
                        eto.start_date <= '2019-06-30' AND
                        eto.end_date >= '2019-07-01'
                 );

注意:我不确定end_date'2019-06-30'还是'2019-07-01'。您的问题没有足够的信息(全天或全天的任何时间)。

您的版本返回所有员工,因为您使用的是LEFT JOIN

答案 1 :(得分:1)

从SQL中,我们无法确定哪个表具有start_date和end_date列。我们怀疑它的employee_time_off表。为了减少歧义,请限定所有列引用

我们可以在WHERE子句中添加一个条件,以便及时删除匹配行。看来我们需要进行<=>=比较才能得到我们想要的结果。

SELECT e.id
     , e.first_name
  FROM employees e
  LEFT
  JOIN employee_time_off o
    ON o.employee_id   = e.id
   AND o.start_date    <= '2019-06-30 00:00:00'
   AND o.end_date      >= '2019-06-30 23:59:59'
 WHERE o.employee_id IS NOT NULL

请注意,对于该查询,如果time_off表中包含以下行,则会得到不同的结果:

 employee_id   start_date            end_date
 -----------   ----------------      -------------------
           1   2019-06-30 00:00:00   2019-06-30 07:24:59
           1   2019-06-30 07:25:00   2019-06-30 23:59:59

当超时表包含这样的行时查询应返回什么?

 employee_id   start_date            end_date
 -----------   ----------------      -------------------
           2   2019-06-29 00:00:00   2019-06-30 11:14:59

规格不清楚。


此外,我们倾向于使用

这样的条件进行日期时间重叠检查
WHERE  foo    >= '2019-06-30 00:00'
  AND  foo    <  '2019-06-30 00:00' + INTERVAL 1 DAY

答案 2 :(得分:0)

  

因此,在这种情况下,id = 1的员工不应出现在结果集中。   但是结果集使所有雇员从1增至6。

我认为您打算在下面编写查询。
但是,如果没有良好的示例数据和预期结果,很难就此事提出有效或可靠的建议。

SELECT 
 employees.*
FROM 
 employees 
WHERE 
employees.id NOT IN (
  SELECT 
   employee_time_off.employee_id
  FROM
   employee_time_off
  WHERE
      employee_time_off.START_DATE < '2019-06-30 00:00:00'
   AND
      employee_time_off.END_DATE > '2019-06-30 12:59:59' 
)