我如何将不满足 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
我有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