SQL 服务器 return 加入的 table where 子句中没有条目时行的结果
SQL Server return result for row when no entry on joined table where clause
我遇到了一个问题,我试图从一个人的时期中提取时间表。如果他们有一个条目,我会得到一行,其中包含他们的姓名和时间表状态。但是,如果他们在一段时间内没有提交两个时间表中的任何一个,则他们根本不会出现在查询中(这意味着当有人跟进他们时他们会被遗漏)。
这是一个简化的示例查询,returns 没有任何内容,因为 resource_id 在 period_end_date 中没有数据大于 where 子句限制:
SELECT time_status_id, last_name
FROM dbo.wh_resource
LEFT JOIN wh_time_report ON wh_time_report.creator_resource_id = wh_resource.resource_id
WHERE wh_resource.resource_id = '31100670'
AND period_end_date >= '2017-01-29'
ORDER BY last_name
我发现制作它 (period_end_date >= '2017-01-29' OR period_end_date IS NULL)
是行不通的,因为他们过去曾输入过数据(如果他们从未输入过,它会把它们拉起来)。
如果由于 period_end_date 没有找到数据,有没有办法简单地放置一个 0?我正在查看 CASE WHERE,但没有成功找到任何地方。
如果他们没有比搜索的条目更新的条目,我宁愿得到一个 time_status_id 0 和这个人的名字。这可能相当简单吗?
我一直在寻求简化调用,但最糟糕的是我可以提取所有姓氏,然后提取所有时间表状态,然后找到不存在的任何条目。下面的这项工作很好(但缺少没有提交时间表的人)
SELECT wh_resource.resource_id, last_name, first_name, narrative_full_name, department_name,
ISNULL(MAX(CASE WHEN wh_time_report.period_end_date = '2017-02-04' THEN time_status_id END),0) as timesheet_status1,
SUM(CASE WHEN date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN ROUND(wh_time_subitem.hours_worked,2) END) as hours_total1,
SUM(CASE WHEN date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as hours_total_old1,
SUM(CASE WHEN allocation_code_id = '91207' AND date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as sick_leave1,
SUM(CASE WHEN allocation_code_id = '91206' AND date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as vacation1,
SUM(CASE WHEN allocation_code_id = '91209' AND date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as personal_leave1,
SUM(CASE WHEN allocation_code_id = '91208' AND date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as holiday1,
SUM(CASE WHEN allocation_code_id = '30091631' AND date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as funeral_leave1,
ISNULL(MAX(CASE WHEN wh_time_report.period_end_date = '2017-02-11' THEN time_status_id END),0) as timesheet_status2,
SUM(CASE WHEN date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN ROUND(wh_time_subitem.hours_worked,2) END) as hours_total2,
SUM(CASE WHEN date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as hours_total_old2,
SUM(CASE WHEN allocation_code_id = '91207' AND date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as sick_leave2,
SUM(CASE WHEN allocation_code_id = '91206' AND date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as vacation2,
SUM(CASE WHEN allocation_code_id = '91209' AND date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as personal_leave2,
SUM(CASE WHEN allocation_code_id = '91208' AND date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as holiday2,
SUM(CASE WHEN allocation_code_id = '30091631' AND date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as funeral_leave2
FROM dbo.wh_resource
JOIN dbo.wh_department_resource ON wh_resource.resource_id = wh_department_resource.resource_id
JOIN dbo.wh_department ON wh_department_resource.department_id = wh_department.department_id
LEFT JOIN wh_time_item ON wh_time_item.user_id = wh_resource.resource_id
LEFT JOIN wh_time_subitem ON wh_time_subitem.time_item_id = wh_time_item.time_item_id
LEFT JOIN wh_time_report ON wh_time_report.creator_resource_id = wh_department_resource.resource_id
WHERE wh_department_resource.is_default_department = 1
AND wh_resource.is_active = 1
AND last_name != 'API.User'
AND wh_department.department_id = '30091606'
AND department_name NOT IN ('Sales', 'Marketing', 'Operations', '')
AND (wh_time_report.period_end_date IN ('2017-02-04', '2017-02-11') OR wh_time_report.period_end_date IS NULL)
GROUP BY wh_resource.resource_id, last_name, first_name, narrative_full_name, hire_date, department_name
ORDER BY last_name
那个查询 returns 73 个结果,有 76 人,所以如果我用
查询来拉人
SELECT * FROM dbo.wh_resource
JOIN wh_department_resource ON wh_resource.resource_id = wh_department_resource.resource_id
WHERE wh_resource.is_active = 1
AND department_id = '30091606'
AND is_default_department ='1'
ORDER BY last_name, first_name
通过检查名称是否存在,我可以在 PHP 的两个查询中获得我需要的所有数据。但我更愿意在一次查询中获得所有信息!
编辑:
使用 SqlZim 的推送,以下查询对我来说运行良好。它可能很混乱,但运行速度很快(比这个正在替换的 1000 个查询快得多,不是开玩笑)。日期将通过 PHP 提供,如果需要,部门 ID 也会提供。
SELECT wh_resource.resource_id, last_name, first_name, narrative_full_name, department_name,
ISNULL(MAX(CASE WHEN T1.period_end_date = '2017-02-04' THEN T1.time_status_id END),0) as timesheet_status1,
SUM(CASE WHEN S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN ROUND(S1.hours_worked,2) END) as hours_total1,
SUM(CASE WHEN S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as hours_total_old1,
SUM(CASE WHEN S1.allocation_code_id = '91207' AND S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as sick_leave1,
SUM(CASE WHEN S1.allocation_code_id = '91206' AND S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as vacation1,
SUM(CASE WHEN S1.allocation_code_id = '91209' AND S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as personal_leave1,
SUM(CASE WHEN S1.allocation_code_id = '91208' AND S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as holiday1,
SUM(CASE WHEN S1.allocation_code_id = '30091631' AND S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as funeral_leave1,
ISNULL(MAX(CASE WHEN T2.period_end_date = '2017-02-11' THEN T2.time_status_id END),0) as timesheet_status2,
SUM(CASE WHEN S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN ROUND(S2.hours_worked,2) END) as hours_total2,
SUM(CASE WHEN S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as hours_total_old2,
SUM(CASE WHEN S2.allocation_code_id = '91207' AND S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as sick_leave2,
SUM(CASE WHEN S2.allocation_code_id = '91206' AND S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as vacation2,
SUM(CASE WHEN S2.allocation_code_id = '91209' AND S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as personal_leave2,
SUM(CASE WHEN S2.allocation_code_id = '91208' AND S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as holiday2,
SUM(CASE WHEN S2.allocation_code_id = '30091631' AND S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as funeral_leave2
FROM dbo.wh_resource
JOIN dbo.wh_department_resource ON wh_resource.resource_id = wh_department_resource.resource_id
JOIN dbo.wh_department ON wh_department_resource.department_id = wh_department.department_id
LEFT JOIN wh_time_item ON wh_time_item.user_id = wh_resource.resource_id
LEFT JOIN wh_time_report T1 ON T1.creator_resource_id = wh_resource.resource_id AND T1.period_end_date = '2017-02-04'
LEFT JOIN wh_time_subitem S1 ON S1.time_item_id = wh_time_item.time_item_id AND S1.date_worked >= '2017-01-29' AND S1.date_worked < '2017-02-05'
LEFT JOIN wh_time_report T2 ON T2.creator_resource_id = wh_resource.resource_id AND T2.period_end_date = '2017-02-11'
LEFT JOIN wh_time_subitem S2 ON S2.time_item_id = wh_time_item.time_item_id AND S2.date_worked >= '2017-02-05' AND S2.date_worked < '2017-02-12'
WHERE wh_department_resource.is_default_department = 1
AND wh_resource.is_active = 1
AND last_name != 'API.User'
AND wh_department.department_id = '30091606'
AND department_name NOT IN ('Sales', 'Marketing', 'Operations', '')
GROUP BY wh_resource.resource_id, last_name, first_name, narrative_full_name, hire_date, department_name
ORDER BY last_name
如果您在 where
中引用 outer join
table(在本例中为左侧)的列,而不允许 null
,您将删除行.
如果将 where
条件移动到加入条件,则可以使用 isnull()
and/or [=] 处理 select
中的 null
s 18=].
您的查询看起来像这样:
select
wr.resource_id
, last_name
, first_name
, narrative_full_name
, department_name
, timesheet_status1 = isnull(max(case when wtr.period_end_date = '2017-02-04' then time_status_id end),0)
, hours_total1 = sum(case when date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then round(wts.hours_worked,2) end)
, hours_total_old1 = sum(case when date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, sick_leave1 = sum(case when allocation_code_id = '91207' and date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, vacation1 = sum(case when allocation_code_id = '91206' and date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, personal_leave1 = sum(case when allocation_code_id = '91209' and date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, holiday1 = sum(case when allocation_code_id = '91208' and date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, funeral_leave1 = sum(case when allocation_code_id = '30091631' and date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, timesheet_status2 = isnull(max(case when wtr.period_end_date = '2017-02-11' then time_status_id end),0)
, hours_total2 = sum(case when date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then round(wts.hours_worked,2) end)
, hours_total_old2 = sum(case when date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
, sick_leave2 = sum(case when allocation_code_id = '91207' and date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
, vacation2 = sum(case when allocation_code_id = '91206' and date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
, personal_leave2 = sum(case when allocation_code_id = '91209' and date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
, holiday2 = sum(case when allocation_code_id = '91208' and date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
, funeral_leave2 = sum(case when allocation_code_id = '30091631' and date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
from dbo.wh_resource as wr
inner join dbo.wh_department_resource as wdr
on wr.resource_id = wdr.resource_id
and wr.is_active = 1
and wr.last_name != 'api.user'
and wdr.is_default_department = 1
inner join dbo.wh_department as wd
on wdr.department_id = wd.department_id
and wd.department_id = '30091606'
and department_name not in ('sales', 'marketing', 'operations', '')
left join wh_time_item as wti
on wti.user_id = wr.resource_id
left join wh_time_subitem as wts
on wts.time_item_id = wti.time_item_id
left join wh_time_report as wtr
on wtr.creator_resource_id = wdr.resource_id
and wtr.period_end_date in ('2017-02-04', '2017-02-11')
group by wr.resource_id, last_name, first_name, narrative_full_name, hire_date, department_name
order by last_name
由于您没有为 period_end_date 提供 table 并且 time_status_id 不确定
但是试试这个
SELECT time_status_id, last_name
FROM dbo.wh_resource
LEFT JOIN wh_time_report
ON wh_time_report.creator_resource_id = wh_resource.resource_id
AND period_end_date >= '2017-01-29'
WHERE wh_resource.resource_id = '31100670'
ORDER BY last_name
对不起,我没有足够的时间来操作您提供的完整查询。
您可以尝试 OUTER APPLY 来获得期望的结果 - 在 table 中没有记录匹配标准的情况下得到零。简短的例子,如何做到这一点:
SELECT
[time_status_id] = a.time_status_id
,[last_name] = a.last_name
,[count] = isnull(b.cnt, 0)
FROM
dbo.wh_resource as a
outer apply
(
select
cnt = count(*)
from
wh_time_report
where
creator_resource_id = a.resource_id
) as b
WHERE a.resource_id = '31100670'
AND a.period_end_date >= '2017-01-29'
ORDER BY a.last_name
我遇到了一个问题,我试图从一个人的时期中提取时间表。如果他们有一个条目,我会得到一行,其中包含他们的姓名和时间表状态。但是,如果他们在一段时间内没有提交两个时间表中的任何一个,则他们根本不会出现在查询中(这意味着当有人跟进他们时他们会被遗漏)。
这是一个简化的示例查询,returns 没有任何内容,因为 resource_id 在 period_end_date 中没有数据大于 where 子句限制:
SELECT time_status_id, last_name
FROM dbo.wh_resource
LEFT JOIN wh_time_report ON wh_time_report.creator_resource_id = wh_resource.resource_id
WHERE wh_resource.resource_id = '31100670'
AND period_end_date >= '2017-01-29'
ORDER BY last_name
我发现制作它 (period_end_date >= '2017-01-29' OR period_end_date IS NULL)
是行不通的,因为他们过去曾输入过数据(如果他们从未输入过,它会把它们拉起来)。
如果由于 period_end_date 没有找到数据,有没有办法简单地放置一个 0?我正在查看 CASE WHERE,但没有成功找到任何地方。
如果他们没有比搜索的条目更新的条目,我宁愿得到一个 time_status_id 0 和这个人的名字。这可能相当简单吗?
我一直在寻求简化调用,但最糟糕的是我可以提取所有姓氏,然后提取所有时间表状态,然后找到不存在的任何条目。下面的这项工作很好(但缺少没有提交时间表的人)
SELECT wh_resource.resource_id, last_name, first_name, narrative_full_name, department_name,
ISNULL(MAX(CASE WHEN wh_time_report.period_end_date = '2017-02-04' THEN time_status_id END),0) as timesheet_status1,
SUM(CASE WHEN date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN ROUND(wh_time_subitem.hours_worked,2) END) as hours_total1,
SUM(CASE WHEN date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as hours_total_old1,
SUM(CASE WHEN allocation_code_id = '91207' AND date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as sick_leave1,
SUM(CASE WHEN allocation_code_id = '91206' AND date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as vacation1,
SUM(CASE WHEN allocation_code_id = '91209' AND date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as personal_leave1,
SUM(CASE WHEN allocation_code_id = '91208' AND date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as holiday1,
SUM(CASE WHEN allocation_code_id = '30091631' AND date_worked >= '2017-01-29' AND date_worked <= '2017-02-04' THEN wh_time_subitem.hours_worked END) as funeral_leave1,
ISNULL(MAX(CASE WHEN wh_time_report.period_end_date = '2017-02-11' THEN time_status_id END),0) as timesheet_status2,
SUM(CASE WHEN date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN ROUND(wh_time_subitem.hours_worked,2) END) as hours_total2,
SUM(CASE WHEN date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as hours_total_old2,
SUM(CASE WHEN allocation_code_id = '91207' AND date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as sick_leave2,
SUM(CASE WHEN allocation_code_id = '91206' AND date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as vacation2,
SUM(CASE WHEN allocation_code_id = '91209' AND date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as personal_leave2,
SUM(CASE WHEN allocation_code_id = '91208' AND date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as holiday2,
SUM(CASE WHEN allocation_code_id = '30091631' AND date_worked >= '2017-02-05' AND date_worked <= '2017-02-11' THEN wh_time_subitem.hours_worked END) as funeral_leave2
FROM dbo.wh_resource
JOIN dbo.wh_department_resource ON wh_resource.resource_id = wh_department_resource.resource_id
JOIN dbo.wh_department ON wh_department_resource.department_id = wh_department.department_id
LEFT JOIN wh_time_item ON wh_time_item.user_id = wh_resource.resource_id
LEFT JOIN wh_time_subitem ON wh_time_subitem.time_item_id = wh_time_item.time_item_id
LEFT JOIN wh_time_report ON wh_time_report.creator_resource_id = wh_department_resource.resource_id
WHERE wh_department_resource.is_default_department = 1
AND wh_resource.is_active = 1
AND last_name != 'API.User'
AND wh_department.department_id = '30091606'
AND department_name NOT IN ('Sales', 'Marketing', 'Operations', '')
AND (wh_time_report.period_end_date IN ('2017-02-04', '2017-02-11') OR wh_time_report.period_end_date IS NULL)
GROUP BY wh_resource.resource_id, last_name, first_name, narrative_full_name, hire_date, department_name
ORDER BY last_name
那个查询 returns 73 个结果,有 76 人,所以如果我用
查询来拉人SELECT * FROM dbo.wh_resource
JOIN wh_department_resource ON wh_resource.resource_id = wh_department_resource.resource_id
WHERE wh_resource.is_active = 1
AND department_id = '30091606'
AND is_default_department ='1'
ORDER BY last_name, first_name
通过检查名称是否存在,我可以在 PHP 的两个查询中获得我需要的所有数据。但我更愿意在一次查询中获得所有信息!
编辑: 使用 SqlZim 的推送,以下查询对我来说运行良好。它可能很混乱,但运行速度很快(比这个正在替换的 1000 个查询快得多,不是开玩笑)。日期将通过 PHP 提供,如果需要,部门 ID 也会提供。
SELECT wh_resource.resource_id, last_name, first_name, narrative_full_name, department_name,
ISNULL(MAX(CASE WHEN T1.period_end_date = '2017-02-04' THEN T1.time_status_id END),0) as timesheet_status1,
SUM(CASE WHEN S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN ROUND(S1.hours_worked,2) END) as hours_total1,
SUM(CASE WHEN S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as hours_total_old1,
SUM(CASE WHEN S1.allocation_code_id = '91207' AND S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as sick_leave1,
SUM(CASE WHEN S1.allocation_code_id = '91206' AND S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as vacation1,
SUM(CASE WHEN S1.allocation_code_id = '91209' AND S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as personal_leave1,
SUM(CASE WHEN S1.allocation_code_id = '91208' AND S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as holiday1,
SUM(CASE WHEN S1.allocation_code_id = '30091631' AND S1.date_worked >= '2017-01-29' AND S1.date_worked <= '2017-02-04' THEN S1.hours_worked END) as funeral_leave1,
ISNULL(MAX(CASE WHEN T2.period_end_date = '2017-02-11' THEN T2.time_status_id END),0) as timesheet_status2,
SUM(CASE WHEN S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN ROUND(S2.hours_worked,2) END) as hours_total2,
SUM(CASE WHEN S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as hours_total_old2,
SUM(CASE WHEN S2.allocation_code_id = '91207' AND S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as sick_leave2,
SUM(CASE WHEN S2.allocation_code_id = '91206' AND S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as vacation2,
SUM(CASE WHEN S2.allocation_code_id = '91209' AND S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as personal_leave2,
SUM(CASE WHEN S2.allocation_code_id = '91208' AND S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as holiday2,
SUM(CASE WHEN S2.allocation_code_id = '30091631' AND S2.date_worked >= '2017-02-05' AND S2.date_worked <= '2017-02-11' THEN S2.hours_worked END) as funeral_leave2
FROM dbo.wh_resource
JOIN dbo.wh_department_resource ON wh_resource.resource_id = wh_department_resource.resource_id
JOIN dbo.wh_department ON wh_department_resource.department_id = wh_department.department_id
LEFT JOIN wh_time_item ON wh_time_item.user_id = wh_resource.resource_id
LEFT JOIN wh_time_report T1 ON T1.creator_resource_id = wh_resource.resource_id AND T1.period_end_date = '2017-02-04'
LEFT JOIN wh_time_subitem S1 ON S1.time_item_id = wh_time_item.time_item_id AND S1.date_worked >= '2017-01-29' AND S1.date_worked < '2017-02-05'
LEFT JOIN wh_time_report T2 ON T2.creator_resource_id = wh_resource.resource_id AND T2.period_end_date = '2017-02-11'
LEFT JOIN wh_time_subitem S2 ON S2.time_item_id = wh_time_item.time_item_id AND S2.date_worked >= '2017-02-05' AND S2.date_worked < '2017-02-12'
WHERE wh_department_resource.is_default_department = 1
AND wh_resource.is_active = 1
AND last_name != 'API.User'
AND wh_department.department_id = '30091606'
AND department_name NOT IN ('Sales', 'Marketing', 'Operations', '')
GROUP BY wh_resource.resource_id, last_name, first_name, narrative_full_name, hire_date, department_name
ORDER BY last_name
如果您在 where
中引用 outer join
table(在本例中为左侧)的列,而不允许 null
,您将删除行.
如果将 where
条件移动到加入条件,则可以使用 isnull()
and/or [=] 处理 select
中的 null
s 18=].
您的查询看起来像这样:
select
wr.resource_id
, last_name
, first_name
, narrative_full_name
, department_name
, timesheet_status1 = isnull(max(case when wtr.period_end_date = '2017-02-04' then time_status_id end),0)
, hours_total1 = sum(case when date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then round(wts.hours_worked,2) end)
, hours_total_old1 = sum(case when date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, sick_leave1 = sum(case when allocation_code_id = '91207' and date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, vacation1 = sum(case when allocation_code_id = '91206' and date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, personal_leave1 = sum(case when allocation_code_id = '91209' and date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, holiday1 = sum(case when allocation_code_id = '91208' and date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, funeral_leave1 = sum(case when allocation_code_id = '30091631' and date_worked >= '2017-01-29' and date_worked <= '2017-02-04' then wts.hours_worked end)
, timesheet_status2 = isnull(max(case when wtr.period_end_date = '2017-02-11' then time_status_id end),0)
, hours_total2 = sum(case when date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then round(wts.hours_worked,2) end)
, hours_total_old2 = sum(case when date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
, sick_leave2 = sum(case when allocation_code_id = '91207' and date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
, vacation2 = sum(case when allocation_code_id = '91206' and date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
, personal_leave2 = sum(case when allocation_code_id = '91209' and date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
, holiday2 = sum(case when allocation_code_id = '91208' and date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
, funeral_leave2 = sum(case when allocation_code_id = '30091631' and date_worked >= '2017-02-05' and date_worked <= '2017-02-11' then wts.hours_worked end)
from dbo.wh_resource as wr
inner join dbo.wh_department_resource as wdr
on wr.resource_id = wdr.resource_id
and wr.is_active = 1
and wr.last_name != 'api.user'
and wdr.is_default_department = 1
inner join dbo.wh_department as wd
on wdr.department_id = wd.department_id
and wd.department_id = '30091606'
and department_name not in ('sales', 'marketing', 'operations', '')
left join wh_time_item as wti
on wti.user_id = wr.resource_id
left join wh_time_subitem as wts
on wts.time_item_id = wti.time_item_id
left join wh_time_report as wtr
on wtr.creator_resource_id = wdr.resource_id
and wtr.period_end_date in ('2017-02-04', '2017-02-11')
group by wr.resource_id, last_name, first_name, narrative_full_name, hire_date, department_name
order by last_name
由于您没有为 period_end_date 提供 table 并且 time_status_id 不确定
但是试试这个
SELECT time_status_id, last_name
FROM dbo.wh_resource
LEFT JOIN wh_time_report
ON wh_time_report.creator_resource_id = wh_resource.resource_id
AND period_end_date >= '2017-01-29'
WHERE wh_resource.resource_id = '31100670'
ORDER BY last_name
对不起,我没有足够的时间来操作您提供的完整查询。 您可以尝试 OUTER APPLY 来获得期望的结果 - 在 table 中没有记录匹配标准的情况下得到零。简短的例子,如何做到这一点:
SELECT
[time_status_id] = a.time_status_id
,[last_name] = a.last_name
,[count] = isnull(b.cnt, 0)
FROM
dbo.wh_resource as a
outer apply
(
select
cnt = count(*)
from
wh_time_report
where
creator_resource_id = a.resource_id
) as b
WHERE a.resource_id = '31100670'
AND a.period_end_date >= '2017-01-29'
ORDER BY a.last_name