У меня проблема, когда я пытаюсь вытащить расписания из периодов для человека. Если у них есть запись, я получаю строку со своим именем и статусом расписания. Но если они не представили ни один из двух расписаний за определенный период времени, они вообще не отображаются в запросе (это означает, что они будут упущены, когда кто-то отправится с ними следить).Результат возврата SQL Server для строки, когда нет записи о соединенной таблице, где статья
Вот упрощенный пример запроса, который не возвращает ничего, как resource_id не имеет данных в period_end_date больше, чем где пределы оговорка:
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)
не будет работать, так как они вошли данные в прошлом (если бы они никогда не были, это бы их подтянуть).
Есть ли способ поставить простой 0, если не было данных, найденных из-за period_end_date? Я смотрел СЛУЧАЯ ГДЕ, но никуда не уходил.
Я бы скорее получил 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
Это один запрос возвращает 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, проверяя, существует ли имя. Но я бы предпочел получить все это в одном запросе!
Редактировать: Используя push SqlZim, у меня есть следующий запрос, который хорошо работает для меня. Это может быть беспорядочно, но он работает быстро (намного быстрее, чем 1000 запросов, которые он заменяет, не шутит). Даты будут предоставлены через PHP, так же как и идентификатор отдела, если это необходимо.
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
Последние два запроса имеют разные условия, поэтому неудивительно, что вы получаете другой счет. Перед составлением выводов следует сравнить сопоставимые запросы. – trincot
префикс всех столбцов с таблицей или псевдонимом, чтобы было понятно, откуда они. – SqlZim
Внесение псевдонима помогло мне, я постараюсь сделать это больше в будущем! –