You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MySQL查询:LEFT JOIN与WHERE无结果时返回NULL值的实现

问题分析与解决方案

当然可以用单条查询实现你的需求!问题出在你把针对schedule表的过滤条件放在了WHERE子句里——左连接后,没有匹配排班记录的员工对应的schedule列都会是NULL,而WHERE里的schedule.deleted = 0和日期范围判断会直接把这些NULL行过滤掉,这就是为什么你只得到了有匹配排班的员工。

修改思路

要保留所有未删除的员工记录,需要把针对schedule表的过滤逻辑从WHERE移到左连接的ON条件中:

  • schedule.deleted = 0放到LEFT JOIN scheduleON子句里,这样只会关联未被删除的排班,同时保留无排班的员工行。
  • 将日期范围判断也移到这个ON条件里,确保只关联当日的排班记录,不会过滤掉无排班的员工。
  • 保留employees.deleted = 0WHERE子句中,因为我们只需要未被标记删除的员工。

最终查询语句

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` 
    AND `schedule`.`deleted` = '0' 
    AND CURDATE() BETWEEN CAST(schedule.start AS DATE) AND CAST(schedule.end AS DATE)
WHERE `employees`.`deleted` = '0';

效果说明

  • 对于有当日有效排班的员工(比如示例中的员工1、4),会返回他们的完整排班信息。
  • 对于没有匹配排班的员工(比如示例中的员工2、3、6),会返回他们的idinitials,其余列自动填充NULL
  • 被标记为deleted=1的员工(示例中的7、8)会被过滤掉,符合你的需求。

内容的提问来源于stack exchange,提问作者Joel

火山引擎 最新活动