Я работаю над отчетом и начал с созданием этого сводной SQL заявления:Сплит итоговых данных по месяцам
SELECT o.description,
sum(t.total_minutes) total_minutes,
sum(n.total_new_minutes) total_new_minutes
FROM job i
INNER JOIN
operation o ON i.operation_id = o.operation_id
CROSS APPLY
(
SELECT SUM(minutes) total_minutes
FROM job_time t
WHERE i.job_id = t.job_id
AND record_date between '1 JAN 2016' and '29 FEB 2016'
) t
CROSS APPLY
(
SELECT SUM(minutes) total_new_minutes
FROM job_time t
WHERE i.job_id = t.job_id
AND record_date between '1 JAN 2016' and '29 FEB 2016'
AND NOT EXISTS (SELECT 1 FROM job_time v WHERE v.record_date < DATEADD(month, DATEDIFF(month, 0, t.record_date), 0) AND v.job_id = t.job_id)
) n
GROUP BY o.description
Структура таблицы:
Table: job
job_id | operation_id
-------------|-------------
1 | 1
2 | 1
3 | 2
4 | 2
Table: operation
operation_id | description
-------------|-------------
1 | 'OP1'
2 | 'OP2'
Table: job_time
job_id | record_date | minutes
-------------|--------------|---------
1 | '1 JAN 2016' | 20
1 | '2 JAN 2016' | 20
2 | '1 JAN 2016' | 20
2 | '1 FEB 2016' | 20
3 | '1 FEB 2016' | 20
3 | '2 FEB 2016' | 20
4 | '2 JAN 2016' | 20
4 | '2 FEB 2016' | 20
Результат моего краткого запроса:
description | total_minutes | total_new_minutes
-------------|---------------|-----------------
'OP1' | 80 | 60
'OP2' | 80 | 60
SQL скрипку: http://sqlfiddle.com/#!6/f28f7e/1/0
Идея состоит в том, чтобы иметь общее количество часов, затрачиваемых на работу в заданном диапазоне данных, а также получать общее количество часов, затрачиваемых на новые рабочие места каждый месяц.
Пример работы 2: 20 минут в январе считаются новыми работами, однако в феврале эти 20 минут потрачены на старую работу.
Моя проблема заключается в том, что я хочу разделить этот результат в месяц на заданном диапазоне, как показано ниже:
description | month |total_minutes | total_new_minutes
-------------|-----------|--------------|-----------------
'OP1' | '01/2016' | 60 | 60
'OP1' | '02/2016' | 20 | 0
'OP2' | '01/2016' | 20 | 20
'OP2' | '02/2016' | 60 | 40
Изменение запроса, чтобы отразить этот результат:
SELECT o.description,
sum(t.total_minutes) total_minutes,
sum(n.total_new_minutes) total_new_minutes,
t.record_month
FROM job i
INNER JOIN
operation o ON i.operation_id = o.operation_id
CROSS APPLY
(
SELECT SUM(minutes) total_minutes, right(convert(varchar(10),t.record_date,103),7) record_month
FROM job_time t
WHERE i.job_id = t.job_id
AND record_date between '1 JAN 2016' and '29 FEB 2016'
GROUP BY right(convert(varchar(10),t.record_date,103),7)
) t
CROSS APPLY
(
SELECT SUM(minutes) total_new_minutes, right(convert(varchar(10),t.record_date,103),7) record_month
FROM job_time t
WHERE i.job_id = t.job_id
AND record_date between '1 JAN 2016' and '29 FEB 2016'
AND NOT EXISTS (SELECT 1 FROM job_time v WHERE v.record_date < DATEADD(month, DATEDIFF(month, 0, t.record_date), 0) AND v.job_id = t.job_id)
GROUP BY right(convert(varchar(10),t.record_date,103),7)
) n
GROUP BY o.description, t.record_month
SQL скрипку: http://sqlfiddle.com/#!6/f28f7e/3/0
Проблема в том, что я не понимаю, как делается соединение между t и n, а в моем dev db с фактическими данными одна операция сообщает больше минут в total_new_minutes, чем total_minutes, чего никогда не может быть, не имеет значения, насколько плохи данные.
Любая идея, что я делаю неправильно здесь, или если я должен полностью изменить запрос?
Есть более чем один подзапрос с именем т в вашем примере. Если вы спросите о больших t и n, я не думаю, что между ними есть какое-либо соединение. Они косвенно связаны на основе базовой записи, с которой они связаны, от временного набора данных, образованного соединением между заданием таблиц и операцией. – DVT