我对基本查询感到困惑,我有2个表employees
和employee_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。
答案 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'
)