对两个 MySQL 查询执行左外连接?

Posted

技术标签:

【中文标题】对两个 MySQL 查询执行左外连接?【英文标题】:Performing a left outer join on two MySQL queries? 【发布时间】:2015-02-06 21:29:51 【问题描述】:

我在调度应用程序中有两个 SQL 查询来帮助检查员工的可用性。我需要执行左外连接,但我似乎无法完全正确地使用语法。

第一个查询获取在给定时间有空并具有执行计划任务的适当资格的员工列表。

    SELECT e.e_id FROM AppointmentTypes a1
    INNER JOIN EmployeeQualifications eq ON a1.type_id = eq.ea_id
    INNER JOIN Employees e ON e.e_id = eq.e_id
    INNER JOIN EmployeeAvaliable ea ON ea.e_id = e.e_id
    INNER JOIN EmployeeTimes et ON et.time_id = ea.time_id
    INNER JOIN AppointmentTimes a2
    INNER JOIN TypeTimes tt ON tt.time_id = a2.time_id AND tt.type_id = a1.type_id
    WHERE et.wednesday = '1'
    AND a1.type_id = '4'
    AND et.start <= '10:00:00' 
    AND et.end > '10:00:00'

第二个查询获取此时已安排活动的员工列表。

    SELECT e.e_id
    FROM AppointmentTypes atp 
    INNER JOIN Appointments a ON atp.type_id = a.type_id 
    INNER JOIN EmployeesAttending ea ON a.a_id = ea.a_id 
    INNER JOIN Employees e ON e.e_id = ea.e_id 
    WHERE date(a.start_time) = '2014-12-10'
    AND ADDTIME(time(a.start_time),'02:00:00') > '10:00:00'
    AND time(a.start_time) < '12:00:00'

左外部加入这些应该会给我一个合格、可用并且当时还没有安排活动的员工列表。

【问题讨论】:

【参考方案1】:

没有左外连接会给你从左边加上右边可以连接的所有内容。在他们不能的地方为空。

我认为你想要做的是获得第一组中的所有内容,而不是第二组中的所有内容。

SELECT e.e_id FROM AppointmentTypes a1
INNER JOIN EmployeeQualifications eq ON a1.type_id = eq.ea_id
INNER JOIN Employees e ON e.e_id = eq.e_id
INNER JOIN EmployeeAvaliable ea ON ea.e_id = e.e_id
INNER JOIN EmployeeTimes et ON et.time_id = ea.time_id
INNER JOIN AppointmentTimes a2
INNER JOIN TypeTimes tt ON tt.time_id = a2.time_id AND tt.type_id = a1.type_id
WHERE et.wednesday = '1'
AND a1.type_id = '4'
AND et.start <= '10:00:00' 
AND et.end > '10:00:00'
AND e.e_id NOT IN (
    SELECT e.e_id
FROM AppointmentTypes atp 
INNER JOIN Appointments a ON atp.type_id = a.type_id 
INNER JOIN EmployeesAttending ea ON a.a_id = ea.a_id 
INNER JOIN Employees e ON e.e_id = ea.e_id 
WHERE date(a.start_time) = '2014-12-10'
AND ADDTIME(time(a.start_time),'02:00:00') > '10:00:00'
AND time(a.start_time) < '12:00:00'
)

【讨论】:

【参考方案2】:

试试这个:

SELECT e.e_id 
FROM AppointmentTypes a1
INNER JOIN EmployeeQualifications eq ON a1.type_id = eq.ea_id
INNER JOIN Employees e ON e.e_id = eq.e_id
INNER JOIN EmployeeAvaliable ea ON ea.e_id = e.e_id
INNER JOIN EmployeeTimes et ON et.time_id = ea.time_id
INNER JOIN AppointmentTimes a2
INNER JOIN TypeTimes tt ON tt.time_id = a2.time_id AND tt.type_id = a1.type_id
LEFT OUTER JOIN (SELECT DISTINCT e.e_id
                 FROM AppointmentTypes atp 
                 INNER JOIN Appointments a ON atp.type_id = a.type_id 
                 INNER JOIN EmployeesAttending ea ON a.a_id = ea.a_id 
                 INNER JOIN Employees e ON e.e_id = ea.e_id 
                 WHERE DATE(a.start_time) = '2014-12-10' AND 
                       ADDTIME(TIME(a.start_time),'02:00:00') > '10:00:00' AND 
                       TIME(a.start_time) < '12:00:00'
                ) AS A ON e.e_id = A.e.e_id  
WHERE et.wednesday = '1' AND a1.type_id = '4' AND 
      et.start <= '10:00:00' AND et.end > '10:00:00' AND
      A.e.e_id IS NULL;

【讨论】:

以上是关于对两个 MySQL 查询执行左外连接?的主要内容,如果未能解决你的问题,请参考以下文章

LINQ 左外连接查询错误:OuterApply 没有适当的键

mysql左外连接

MySql - 在查询中连接左外连接

真正的左外连接

将两个查询的左外连接转换为 LINQ

MySql的回顾五:多表查询下(内联/左外/右外/自连接/交叉)-1999语法