我需要让最近90名雇佣的员工在过去4周内每次都被终止。这是一份滚动报告。
员工表就像这样:
id hired_date term_date
3 07/1/2011 09/01/2011
4 07/18/2011 NULL (NULL means still active)
5 01/20/2009 08/23/2011
6 05/30/2011 8/22/2011
7 7/20/2011 7/23/2011
报告将采用这种格式。 Id#4,5将被忽略,因为#4仍处于活动状态,#5在90天之前被雇用。
Week ending Terminated employees hired within past 90 days
09/03/2011 2 --(id 3,7)
8/27/2011 2 --(id 6,7)
..
..
我有一个日期表,但它只包含week_start_date,week_end_date和week_number。我是否需要创建一个包含90天期限的文件?
我被困在过去90天内我只能为员工做这件事,然后计算过去4周的每一天。
SQL Server 2008
修改 我想我很亲密。我正在测试它。 All_termed_employees是任何日期范围内已终止员工的列表。周表现在包含与之相关的每周的ninety_begin_date和ninety_end_date。
select wk.ninety_end, count(h.id)
FROM @weeks wk
LEFT JOIN all_termed_employees h
ON h.hire_date <= wk.ninety_end and h.hire_date >= wk.ninety_begin
and .termination_date <= wk.ninety_end AND h.termination_date >= wk.ninety_begin
ORDER BY d.id
GROUP BY wk.ninety_end
答案 0 :(得分:4)
;WITH n(n) AS
-- just 4 rows - makes it easy to extend to 5 weeks, 6 weeks, etc.
( SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 ),
d(dt) AS
-- single row with the end of the current week
-- this could be a variable but I get a lot of flack for not inlining
( SELECT dt = CONVERT(DATE, DATEADD(DAY,
7-DATEPART(WEEKDAY, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP))),
w(dt) AS
-- get the end of each week based on the rows in n
( SELECT DATEADD(WEEK, -n.n, d.dt) FROM n CROSS JOIN d )
SELECT
w.dt, SUM(CASE
WHEN e.term_date >= DATEADD(DAY, -90, w.dt)
AND e.term_date < DATEADD(DAY, 1, w.dt)
AND e.hired_date >= DATEADD(DAY, -90, w.dt)
AND e.hired_date < DATEADD(DAY, 1, w.dt)
THEN 1 ELSE 0 END)
FROM dbo.Employees AS e
CROSS JOIN w
GROUP BY w.dt
ORDER BY w.dt DESC;
答案 1 :(得分:2)
这样的事情怎么样?
EMP模拟您的员工表。 PAST_FOUR_WEEKS是一个简单的4行内存表,用于标识报告周期。然后我计算雇用和期限日期之间的差异,如果它小于或等于90,我们将其计为1(达到阈值)或0)。然后,我将在给定时间段内满足所有阈值的总和
; WITH EMP (id, hired_date, term_date) AS
(
select 3, CAST('2011-07-01' AS datetime), CAST('2011-09-01' AS datetime)
union all select 4, '2011-06-18', null
union all select 5, '01/20/2009','08/23/2011'
union all select 6, '05/30/2011','8/22/2011'
union all select 7, '7/20/2011','7/23/2011'
)
, PAST_FOUR_WEEKS (period, period_rank) AS
(
-- magic goes here to determine end of week
SELECT CURRENT_TIMESTAMP, 1
UNION ALL SELECT dateadd(week, -1, CURRENT_TIMESTAMP) , 2
UNION ALL SELECT dateadd(week, -2, CURRENT_TIMESTAMP) , 3
UNION ALL SELECT dateadd(week, -3, CURRENT_TIMESTAMP) , 4
)
, HIRED_TERMED_DIFF AS
(
SELECT
*
, DATEDIFF(d, E.hired_date, coalesce(E.term_date, '9999-12-31T23:59:59.997')) AS duration
, CASE WHEN DATEDIFF(d, E.hired_date, coalesce(E.term_date, '9999-12-31T23:59:59.997')) < 91 THEN 1 ELSE 0 END AS threshold_met
FROM
EMP E
)
SELECT
PFW.period
, SUM(HTD.threshold_met) AS [Terminated employees hired within past 90 days]
FROM
PAST_FOUR_WEEKS PFW
LEFT OUTER JOIN
HIRED_TERMED_DIFF HTD
ON HTD.hired_date BETWEEN DATEADD(day, -90, PFW.period) AND PFW.period
GROUP BY
PFW.period
ORDER BY
1 DESC
, 2
示例输出
period Terminated employees hired within past 90 days
2011-09-01 14:46:29.243 2
2011-08-25 14:46:29.243 3
2011-08-18 14:46:29.243 3
2011-08-11 14:46:29.243 3