我有一张表,员工历史如下
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
我想要的是一个查询,为每个曾在Sales中工作的人提供:
ID | DeptBefore | DeptAfter | CurrentDept
1 | Marketing | | Sales
2 | ebusiness | IT | IT
3 | | Warehouse | Warehouse
目前我看到没有更简单的方法可以做到这一点,然后以递归方式查询每一行的表格。
我很想创建一个每天填充一次的“临时”表并运行查询。
我正在使用SQL Server和C#(ASP.NET),因为这些提供了其他更简单的解决方案。
我希望一切都有道理。
谢谢,
答案 0 :(得分: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
。
答案 1 :(得分: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