2015-04-07 29 views
0

下面的查詢一些條件的一定年限選擇虛擬數據返回僱員的所有ExceptionDays:我需要生成開始的招聘年份虛擬ExceptionDays基於從主查詢

SELECT 
    idEmployee, idExceptionDayType, 
    YEAR(startDate) year, 
    SUM (days) total 
FROM 
    ExceptionDays ed 
GROUP BY idEmployee, idExceptionDayType, YEAR(startDate) 

僱員直到今年。如果當前員工的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引用第一個查詢是需要的,所以查詢會變得有效,但我不知道我應該怎麼做。

有人可以幫我一點點嗎? 在此先感謝,

回答

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 
0

您可以嘗試這樣的事情。

  1. 獲取所有不同年份從日曆
  2. 交叉聯接全體員工和過濾得到的只有這些年員工已經加入
  3. 不具有在ExceptionDays的具體年份的條目
  4. 篩選只有那些員工後

查詢

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