【问题标题】:How do i include data from a joined table that doesnt meet the WHERE condition as a null value(SQL)如何将不符合 WHERE 条件的联接表中的数据包含为空值(SQL)
【发布时间】:2019-08-26 21:23:27
【问题描述】:

我有两张表employees 和 Medical leave,通过Employee ID 关联,基本上Medical leave 表会有一个员工多个休假的多个数据,我想按月份过滤掉数据病假,并将在过滤月份未发生病假的员工包含为空值。

       EMPLOYEES                  MEDICAL
    |employee|ID|             |ID|DateOfLeave|
         A     1                1   2019/1/3
         B     2                1   2019/4/15
         C     3                2   2019/5/16
         D     4

我提出的 sql 语句过滤了休假的特定月份,并计算了他们在该月(例如 1 月)休假的次数,它还包括没有任何休假的员工为“0”,但是1月份没有病假的员工根本没有出现在结果集中,我如何才能显示他们在一月份有0个病假?

select employees.employee, employees.ID,
 count(medical.DateOfLeave) as NumberOfLeaves
from employees
left outer join medical on employees.ID = medical.ID
where (MONTH(DateOfLeave) = 1) or (medical.DateOfLeave is null)
group by employees.employee,employees.ID
           RESULT SET
    |Employee|ID|NumberOfLeaves|
        A      1      1
        C      3      0   
        D      4      0

如您所见,B 消失了,但我希望它在结果集中显示为“0”,就像员工 C 和 D 一样

我知道这是因为员工 B 的医疗数据不符合 where 子句的条件,但是我如何编写一个语句,其中包含在结果集中没有出现在 1 月的病假为 0 的员工??

【问题讨论】:

    标签: sql sql-server outer-join


    【解决方案1】:

    您的查询仅显示 1 月份休假或根本没有休假的员工的结果。

    相反,如果有指定月份的记录,您只想加入医疗表中的记录,然后您将对结果进行分组并从那里获取计数。

    为此,您需要更改加入条件以包含月份过滤器。

    这是一个使用表变量的工作示例

    DECLARE @Employees TABLE (ID INT, Employee CHAR(1))
    DECLARE @Medical TABLE (ID INT, DateOfLeave DATE)
    
    INSERT INTO @Employees
    VALUES (1, 'A'), (2,'B'), (3,'C'), (4, 'D')
    
    INSERT INTO @Medical 
    VALUES (1, '2019-01-03'), (1, '2019-04-15'), (2, '2019-05-16')
    
    SELECT          e.employee, 
                    e.ID,
                    count(m.DateOfLeave) AS NumberOfLeaves
    FROM            @Employees e
    LEFT OUTER JOIN @Medical m ON   e.ID = m.ID AND MONTH(DateOfLeave) = 1
    GROUP BY        e.employee,e.ID
    

    【讨论】:

      【解决方案2】:

      左外连接会先加入表再过滤。在您的情况下, B 在连接本身中被忽略了,这就是过滤器不起作用的原因。你可以试试这个

      select employees.employee, employees.ID,
       nvl(count(medical.DateOfLeave),0) as NumberOfLeaves
      from employees
      left outer join (select * from medical 
      where (MONTH(DateOfLeave) = 1)) 
      on employees.ID = medical.ID
      group by employees.employee,employees.ID
      

      或者你也可以试试这个

         select e.id, employee, count(dateofleave)
      from employee e, medical m
      where e.id = m.id
      and month(m.DateOfLeave) = 1
      group by e.id, employee
      UNION ALL
      select id, employee, 0
      from employee e
      where not exists(select 1 from medical m
      where e.id = m.id
      and month(m.DateOfLeave) = 1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-21
        • 2011-11-21
        • 1970-01-01
        • 2022-12-10
        • 1970-01-01
        • 2022-10-23
        • 1970-01-01
        • 2022-01-23
        相关资源
        最近更新 更多