我有一个问题,我正试图从一个人的时间段拉出时间表。如果他们有一个条目,我会得到一个他们的名字和时间表状态的行。但是如果他们在一段时间内没有提交两个时间表中的任何一个,那么他们根本不会出现在查询中(这意味着当有人跟随他们时他们会被错过)。
这是一个简单的示例查询,它不返回任何内容,因为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但没有成功到达任何地方。
如果他们没有比搜索到的更新的条目,我宁愿得到一个0的time_status_id和该人的姓名。这可能相当简单吗?
我正在寻求简化调用,但最糟糕的是我可以提取所有姓氏,然后提取所有时间表状态,然后查找不存在的任何条目。以下工作做得很好(但没有提交任何时间表的人失踪)
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
一个查询返回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
答案 0 :(得分:1)
如果您在outer join
中引用where
表的列(在本例中为左侧)而不允许null
,则您将删除行。
如果您将where
条件移至加入条件,则可以使用null
和/或select
处理isnull()
中的coalesce()
。
对于您的查询,看起来像这样:
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
答案 1 :(得分:0)
因为你没有为period_end_date提供表格而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
答案 2 :(得分:0)
请原谅,但我没有足够的时间来操作您提供的完整查询。 您可以尝试 OUTER APPLY 来获得所需的结果 - 如果表中没有匹配cirteria的记录,则大小写为零。简短的例子,如何做到这一点:
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