【问题标题】:Multiple table join with condition from one table多表连接与一张表的条件
【发布时间】:2014-01-29 17:01:28
【问题描述】:

如果其他地方已经讨论过这样的事情,我提前道歉,但如果有,我找不到它(我什至不知道如何搜索这样的事情)。我正在尝试加入两个表,“员工”和“离开”。我想列出“员工”表中的每个员工,并使用“休假”表中的休假数据填充报告,其中“休假日期”(休假表中的 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”之后有休假记录的个人的 ONE 记录。我想要员工表中的员工记录的完整列表,其中包含休假表中的可用数据(如果没有,则为空白),其中休假表中的“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   |
+-----+----------+---------------+---------------+--------------+

【问题讨论】:

    标签: sql select left-join


    【解决方案1】:

    这是因为您的 WHERE 条件。

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

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

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

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

    【讨论】:

    • 你说的容易!我不知道为什么我没有想到。非常感谢,OGHaza 和 DRapp!效果很好!
    【解决方案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
    

    【讨论】:

    • 既然你提到了它,那正是我在实践中的做法;)
    【解决方案3】:

    尝试在这种情况下使用完全外连接。

    来自 MSDN

    完全外连接或完全连接返回两个表中的所有行,匹配可以匹配的行,并在不存在匹配行的地方放置 NULL。

    【讨论】:

      猜你喜欢
      • 2021-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-22
      相关资源
      最近更新 更多