我对mysql查询有问题。
这是我的三张table:
员工:
id initials deleted
------ -------- ---------
1 TV 0
2 AH 0
3 JE 0
4 MA 0
5 MJ 0
6 CE 0
7 KB 1
8 KL 1
日程安排:
id place start end deleted
------ -------------- ------------------- ------------------- ---------
1 Somewhere 2018-05-11 16:48:17 2018-05-15 16:48:26 0
2 Somewhere else 2018-05-12 16:48:50 2018-05-14 16:48:55 1
3 Here 2018-05-13 00:00:00 2018-05-13 00:00:00 0
4 Not here 2018-05-18 16:49:42 2018-05-16 16:49:48 0
和时间表链接:
id id_employee id_schedule
------ ----------- -------------
1 1 1
2 1 2
3 4 3
4 5 4
我想要一个要求,返回所有有关的日期为每个员工的一天。即使员工没有找到任何记录,我也希望查询在其他列中返回其带有null的缩写。
以下是我当前的查询:
SELECT
`employees`.`id`,
`employees`.`initials`,
`schedule`.`place`,
`schedule`.`start`,
`schedule`.`end`,
`schedule`.`deleted`
FROM
`employees`
LEFT JOIN `schedule_link`
ON (
`employees`.`id` = `schedule_link`.`id_employee`
)
LEFT JOIN `schedule`
ON (
`schedule_link`.`id_schedule` = `schedule`.`id`
)
WHERE (
`employees`.`deleted` = '0'
AND `schedule`.`deleted` = '0'
)
AND (
DATE(CURDATE()) BETWEEN CAST(schedule.start AS DATE)
AND CAST(schedule.end AS DATE)
)
这将返回以下数据:
id initials place start end deleted
------ -------- --------- ------------------- ------------------- ---------
1 TV Somewhere 2018-05-11 16:48:17 2018-05-15 16:48:26 0
4 MA Here 2018-05-13 00:00:00 2018-05-13 00:00:00 0
这是正确的,但我想要的是以下结果:
id initials place START END deleted
------ -------- --------- ------------------- ------------------- ---------
1 TV Somewhere 2018-05-11 16:48:17 2018-05-15 16:48:26 0
4 MA Here 2018-05-13 00:00:00 2018-05-13 00:00:00 0
2 AH NULL NULL NULL 0
3 JE NULL NULL NULL 0
5 MJ NULL NULL NULL 0
6 CE NULL NULL NULL 0
一个请求就可以得到这个结果吗?
事先谢谢你的帮助。
2条答案
按热度按时间fxnxkyjh1#
我的一般看法(由于我不在电话atm机上发帖,所以没有测试查询):
你应该使用
RIGHT JOIN
第二次加入你的查询。您还需要附加where子句,即。
where employees.id is not null
别忘了利用ifull()
对于明细表中的所有字段,即。ifnull(schedule_link.id, schedule_link.id, schedule.myfield)
请注意,这应该是为所有领域,你想显示出来的schedule
此查询中的表希望这些指南能对你有所帮助。
zzzyeukh2#
你需要把所有的条件,除了第一个表中
on
条款。你的where
子句将外部联接转换为内部联接。我还有一些建议:
笔记:
表别名使查询更易于编写和读取。
反勾号只会使查询更难读写。
不要使用
start
以及end
作为列名(即,如果可以,重命名它们)。它们是关键字(虽然不是保留的),因此它们在sql语句中还有其他用途。我猜是的
deleted
是数字。不要使用单引号进行比较(除非列实际上是字符串)。CURDATE()
已经是约会了。不需要转换。我不建议使用
BETWEEN
与日期,因为一个挥之不去的时间部分的可能性。但是,您使用的是显式转换,因此代码明确地执行您想要的操作(可能会冒不使用可用索引的风险)。编辑:
我懂了。因为日期条件在第三个表中,而不是在第二个表中,所以会得到重复的行。我想这会解决你的问题:
这将包括每一个在时间框架上没有匹配项的员工。你还是会得到所有的唱片
schedule
如果有多个匹配项。实际上,您可以在不使用子查询的情况下表达这一点:
我发现子查询版本更容易理解。