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) 以防它们提供其他更简单的解决方案。

我希望一切都说得通。

谢谢,

4

2 回答 2

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
于 2012-08-13T10:15:48.727 回答
1

从您的数据看来,您需要immediately销售部门之前和之后的部门。例如; 你没有表明约翰史密斯是从实习生开始的。

注意:如果有人在两个不同的场合从事销售工作,您可能需要考虑您想要的结果。

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

于 2012-08-13T09:04:34.730 回答