Агрегировать N-раз (по разделам) в одном запросе?КТР? - PullRequest
1 голос
/ 04 августа 2011

Чистый прокат для диапазона дат

У меня есть набор данных сотрудника с этими полями. дата окончания равна нулю, если они все еще активны.

id   |    hire date    | termination date
1           7/25/11     |         null
2           12/01/10    |  7/30/11
3           7/20        |  null
4           7/16        | 7/29/11

То, что мне нужно получить за 13-недельный период:

week ending date     Net hires
07-17                   1
07-24                   1
07-31          -1

...

Я начал делать это с помощью CTE, а затем с помощью профсоюзов, потому что бросил попытки выяснить это лучше. Я должен сделать это и для некоторых других полей, так что, может быть, есть лучший способ, может быть, используя pivot / unpivot?

Грубый псевдокод того, что у меня сейчас.

;with foo
as
(
select *
from employee
--joins and conditions
)
select @report_date, sum(case when hire date > report_date-7 and hire_date < report_date then 1 else 0 end)(

... etc

Я позабочусь о датах без найма / прекращения позже.

1 Ответ

4 голосов
/ 04 августа 2011

Тот факт, что вы складываете все эти UNION вместе с жестко закодированным столбцом, должен указывать на то, что вы где-то упускаете набор. В данном случае это набор недель. Поместите их в таблицу (постоянную, временную или виртуальную через CTE), и этот запрос станет тривиальным.

SELECT
    WKS.start_date,
    COUNT(E.employee_id)
FROM
    Report_Weeks WKS
LEFT OUTER JOIN Employees E ON
    E.hire_date > WKS.start_date AND
    E.hire_date < WKS.end_date
GROUP BY
    WKS.start_date
ORDER BY
    WKS.start_date

Поскольку вы ссылаетесь на "чистые" наймы, я предполагаю, что вы хотите работать и в терминациях. Вы можете сделать это, превратив его в SUM(CASE...), где вы используете 1 для новых сотрудников, 0 для людей за пределами этой недели или которые были наняты, а затем уволены в течение той же недели, и -1 для увольнений.

Как указывает JNK, порядок имеет значение в выражении CASE. Также вы можете использовать ELSE для обработки значений 0. Я бы предложил что-то вроде этого:

CASE
    WHEN
        E.hire_date BETWEEN WKS.start_date AND WKS.end_date AND
        E.termination_date > WKS.end_date THEN 1
    WHEN
        E.termination_date BETWEEN WKS.start_date AND WKS.end_date AND
        E.hire_date < WKS.end_date THEN -1
    ELSE 0
END

Поскольку я использовал BETWEEN, вам необходимо убедиться, что дата начала вашей недели не совпадает с датой окончания предыдущей недели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...