2012-08-13 72 views
0

我有一個表,有以下單查詢基於初始列列返回多行

ID | Current_Dept | Dept_Start_Date | Name 
1 | Sales | 2012-01-01 | John Smith 
1 | Marketing | 2010-01-01 | John Smith 
1 | Intern | 2008-01-01 | John Smith 
2 | IT | 2012-01-01 | Sue Jones 
2 | Sales | 2011-01-01 | Sue Jones 
2 | eBusiness | 2010-10-01 | Sue Jones 
3 | Warehouse | 2012-01-01 | Bobby Ray 
3 | Sales | 2009-01-01 | Bobby Ray 

員工的歷史,我想在查詢給誰曾經在銷售工作大傢什麼:

ID | DeptBefore | DeptAfter | CurrentDept 
1 | Marketing |   | Sales 
2 | ebusiness | IT  | IT 
3 |   | Warehouse | Warehouse 

此刻,我看到沒有更簡單的方法做到這一點,然後遞歸查詢每一行的表。

我很想創建一個「臨時」表,每天填充一次,然後運行查詢。

我正在使用SQL Server和C#(ASP.NET)來提供其他更簡單的解決方案。

我希望一切都有道理。

感謝,

+0

您是否嘗試檢索曾在銷售部門工作過的員工名單? – 2012-08-13 09:00:24

回答

1

從您的數據也顯示你的部門immediately前和銷售部門後想。例如;你並沒有表明John Smith是以實習生身份開始的。

注意:如果某人在兩次不同的場合爲銷售工作,您可能需要考慮所需的結果。

WITH 
    sequenced AS 
(
    SELECT 
    *, 
    ROW_NUMBER() OVER (PARTITION BY id ORDER BY dept_start_date DESC) AS sequence_id 
    FROM 
    yourTable 
) 
SELECT 
    salesRecord.id, 
    prevRecord.current_dept  AS DeptBefore, 
    nextRecord.current_dept  AS DeptAfter, 
    lastRecord.current_dept  AS DeptCurrent 
FROM 
    sequenced  AS salesRecord 
LEFT JOIN 
    sequenced  AS prevRecord 
    ON prevRecord.id   = salesRecord.id 
    AND prevRecord.sequence_id = salesRecord.sequence_id - 1 
LEFT JOIN 
    sequenced  AS nextRecord 
    ON nextRecord.id   = salesRecord.id 
    AND nextRecord.sequence_id = salesRecord.sequence_id + 1 
LEFT JOIN 
    sequenced  AS lastRecord 
    ON lastRecord.id   = salesRecord.id 
    AND lastRecord.sequence_id = 1 
WHERE 
    salesRecord.CurrentDept = 'Sales' 

通過以降序排序的項目,將當前紀錄總是sequence_id = 1

+0

使用這個工程太棒了!從未聽說過OVER,在Visual Studio GUI中遇到過問題。 http://stackoverflow.com/questions/5784072/no-support-for-over-in-ms-sql-server-2005告訴我使用服務器管理Studio,只需鍵入查詢。 – jimmy 2012-08-13 12:32:53

1

使用CTE可以幫助你。

DECLARE @Temp TABLE 
(
    ID INT, 
    current_dept NVARCHAR(100), 
    Dept_Start_Date DATETIME, 
    Name NVARCHAR(100) 
) 

INSERT INTO @Temp 
(ID, current_dept, Dept_Start_Date, Name) 
VALUES 
(1, 'Sales', '2012-01-01', 'John Smith'), 
(1, 'Marketing', '2010-01-01', 'John Smith'), 
(1, 'Intern', '2008-01-01', 'John Smith'), 
(2, 'IT', '2012-01-01', 'Sue Jones'), 
(2, 'Sales', '2011-01-01', 'Sue Jones'), 
(2, 'eBusiness', '2010-01-01', 'Sue Jones'), 
(3, 'Warehouse', '2012-01-01', 'Bobby Ray'), 
(3, 'Sales', '2009-01-01', 'Bobby Ray') 

DECLARE @current_dept NVARCHAR(100) = 'Sales' 
;WITH CurrentDeptCTE AS 
(
    SELECT ID, current_dept, Dept_Start_Date, Name, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY Dept_Start_Date DESC) AS SEQUENCE 
    FROM @Temp 
) 
SELECT SalesDept.ID, DeptBefore.current_dept AS 'DeptBefore', DeptAfter.current_dept  AS 'DeptAfter', CurrentDept.current_dept AS 'CurrentDept' 
FROM 
(
    SELECT ID, SEQUENCE 
    FROM CurrentDeptCTE 
    WHERE current_dept = @current_dept 
) SalesDept 
LEFT JOIN CurrentDeptCTE AS DeptBefore ON SalesDept.ID = DeptBefore.ID AND   SalesDept.SEQUENCE = DeptBefore.SEQUENCE - 1 
LEFT JOIN CurrentDeptCTE AS DeptAfter ON SalesDept.ID = DeptAfter.ID AND SalesDept.SEQUENCE = DeptAfter.SEQUENCE + 1 
LEFT JOIN 
(
    SELECT ID, current_dept 
    FROM CurrentDeptCTE 
    WHERE SEQUENCE = 1 
) CurrentDept ON SalesDept.ID = CurrentDept.ID