多个表连接条件来自一个表

时间:2014-01-29 17:01:28

标签: sql select left-join

如果这样的事情已经在其他地方讨论过,我提前道歉,但如果有,我无法找到它(我甚至不确定如何搜索这样的事情)。我正在尝试加入两个表,“员工”和“离开”。我想列出“员工”表中的每个员工,并使用“离开”表中的休假数据填充报告,其中“休假日期”(休假表中的bdate列)大于2014年1月1日(或当前年份) )。问题是并非每个员工都有数据,所以我发现普通的连接只从实际有数据的员工那里获取数据。我认为我想要的是一个左连接,但我只从两个表中获取记录,其中两个表中实际上有该员工的数据(希望这是有道理的)。

Select bunch_of_columns, leave.bdate, SUM(leave.Vhours) as TotalVacationHours, SUM(leave.shours) as TotalSickHours
from employees 
left join leave on employees.id=leave.id
where employees.user_active ='1' AND leave.BDate >= '2014-01-01'
group by employees.id
Order by employees.user_last

这会产生一个在“2014-01-01”之后有休假记录的个人记录。我希望员工表中的员工记录的完整列表包含离开表中的可用数据(如果没有,则为空白),其中离开表中的“bdate”列大于新年。

我想要这个:

+-----+----------+---------------+---------------+--------------+
|ID   | Name     | Vacation Hrs  | Sick Hrs      | Date         |
+-----+----------+---------------+---------------+--------------+
|   1 | Bob      | 5             | 8             | 2014-01-01   |
|   2 | Lucy     | NULL          | NULL          | NULL         |
|   3 | Jerry    | NULL          | NULL          | NULL         |
|   4 | Dieter   | 3             | 5             | 2014-01-08   |
|   5 | Sprockets| NULL          | NULL          | NULL         |
+-----+----------+---------------+---------------+--------------+

不是这个:

+-----+----------+---------------+---------------+--------------+
| row | Name     | Vacation Hrs  | Sick Hrs      | Date         |
+-----+----------+---------------+---------------+--------------+
|   1 | Bob      | 5             | 8             | 2014-01-01   |
|   4 | Dieter   | 3             | 5             | 2014-01-08   |
+-----+----------+---------------+---------------+--------------+

3 个答案:

答案 0 :(得分:3)

这是因为你的WHERE条件。

leave.BDate >= '2014-01-01'

如果您执行LEFT JOIN,然后将右表中的列过滤为不能NULL的内容,则相当于执行INNER JOIN

如果没有休假日期,则记录不符合标准。你应该检查一下:

(leave.BDate >= '2014-01-01' OR leave.BDate IS NULL)

答案 1 :(得分:2)

写它的另一种方式(正如OGHaza所指出的)是将日期条件应用于JOIN部分

Select 
      bunch_of_columns, 
      leave.bdate, 
      COALESCE( SUM(leave.Vhours), 0 ) as TotalVacationHours, 
      COALESCE( SUM(leave.shours), 0 ) as TotalSickHours
   from 
      employees 
         left join leave 
            on employees.id=leave.id
            AND leave.BDate >= '2014-01-01'
   where 
      employees.user_active ='1' 
   group by 
      employees.id
   Order by 
      employees.user_last

答案 2 :(得分:0)

尝试使用Full Outer Join来处理这种情况。

来自MSDN

完全外连接或完全连接返回两个表中的所有行,匹配可以进行匹配的行,并将NULL放在没有匹配行的位置。