以下查询返回员工的所有ExceptionDays:
SELECT
idEmployee, idExceptionDayType,
YEAR(startDate) year,
SUM (days) total
FROM
ExceptionDays ed
GROUP BY idEmployee, idExceptionDayType, YEAR(startDate)
我需要从员工的招聘年份开始生成虚拟ExceptionDays,直到当前年份。如果当前员工的ExceptionDays表中已存在一年,则此子查询不应创建虚拟数据。
所以基本上,如果员工在2010年被聘用并且它在2014年和2015年的ExceptionDays表中有数据,那么查询应该返回2010,2011,2012,2013作为虚拟数据,而对于2014年和2015年,它应该得到有效数据
为了生成虚拟数据,我使用了几年的临时日历:
SELECT
1 as idEmployee,1 as idExceptionDayType,YEAR(c.date) year,0 total
FROM
TMP_CALENDAR c WITH (NOLOCK)
WHERE
YEAR(c.date) >= 2012
AND YEAR(c.date) < YEAR(GETDATE())
GROUP BY YEAR(c.date)
第二个子查询应该以某种方式连接到第一个查询,期望的查询将变为:
SELECT
ED.idEmployee,1 as idExceptionDayType,YEAR(c.date) year,0 total
FROM
TMP_CALENDAR c WITH (NOLOCK)
JOIN Employees E ON ED.idEmployee = E.idEmployee
WHERE
YEAR(c.date) >= YEAR(e.hiringDate)
AND YEAR(c.date) < YEAR(GETDATE()) AND YEAR <> YEAR(ed.year)
GROUP BY YEAR(c.date)
我们可以看到需要对第一个查询进行ED引用,因此查询会变得有效,但我不确定我该怎么做。
有人可以帮我一点点吗? 提前谢谢,
答案 0 :(得分:1)
这种类型的查询背后的想法是首先生成输出行 - 使用CROSS JOIN
获取所有年份和员工,然后使用其他逻辑来引入其他值。
以下版本仅使用ExceptionDays
来获取所有年份,假设每年至少有一天这样。您还可以使用y
子查询的日历表:
SELECT e.idEmployee, COALESCE(ed.idExceptionDayType, 1) as idExceptionDayType
y.year, COALESCE(SUM(ed.days), 0) as total
FROM (SELECT DISTINCT idEmployee FROM ExceptionDays) e CROSS JOIN
(SELECT DISTINCT YEAR(startDate) as year FROM ExceptionDays) y LEFT JOIN
ExceptionDays ed
ON ed.idEmployee = e.idEmployee and
y.year BETWEEN YEAR(ed.startDate) AND year(GETDATE())
GROUP BY e.idEmployee, ed.idExceptionDayType, y.year
答案 1 :(得分:0)
你可以尝试这样的事情。
<强>查询强>
SELECT
E.idEmployee,1 as idExceptionDayType,calendar_year,0 total
FROM
(
SELECT YEAR(c.date) calendar_year
FROM TMP_CALENDAR
GROUP BY YEAR(c.date)
)c
CROSS JOIN Employees E
LEFT JOIN ExceptionDays ed
ON ED.idEmployee = E.idEmployee
AND ed.YEAR(startDate) = calendar_year
WHERE calendar_year >= YEAR(e.hiringDate)
AND calendar_year < YEAR(GETDATE())
AND ED.idEmployee IS NULL