我如何将不满足 WHERE 条件的连接 table 中的数据包含为空值 (SQL)

How do i include data from a joined table that doesnt meet the WHERE condition as a null value(SQL)

我有2 tables employees 和 Medical leave ,它们是通过Employee ID关联的,基本上Medical leave table 会有一个员工多次休假的多个数据,我想按请病假的月份过滤数据,将过滤月份没有请病假的员工作为空值包含进来。

       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 语句过滤了休假的具体月份,并计算了他们在那个月(例如一月)休假的次数,它还包括没有休假的员工'0',但是在 1 月份没有休病假的员工根本不会出现在结果集中,我如何显示他们在 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?

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

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

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

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

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

left outer join会先加入table再过滤。在你的情况下,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