2017-04-10 71 views
1

我有一张保存学生信息的表。如何在SQL服务器中找到记录中的更改

+==========================================+ 
| ID  | Department  | Date   | 
+==========================================+ 
| 001  | English   | Feb 3 2017 | 
| 001  | English   | Feb 4 2017 | 
| 001  | Science   | Mar 1 2017 | 
| 001  | Maths   | Mar 2 2017 | 
| 001  | Maths   | Mar 21 2017 | 
| 001  | Maths   | Apr 2 2017 | 
| 001  | English   | Apr 7 2017 | 
| 002  | Maths   | Feb 1 2017 | 
| 002  | Maths   | Apr 7 2017 | 
| 003  | Maths   | Apr 3 2017 | 
| 003  | Maths   | Apr 7 2017 | 
| 004  | Science   | Feb 1 2017 | 
| 004  | Science   | Mar 1 2017 | 
| 004  | Maths   | Apr 7 2017 | 
| 004  | English   | Apr 9 2017 | 
+==========================================+ 

在上表中,我需要在学生的部门首选项发生更改时获取学生记录列表。学生也有机会再次回到同一部门。因此,对于上述样本数据的记录列表中返回的将是

学生001

| 001  | English   | Feb 4 2017 | 
| 001  | Science   | Mar 1 2017 | 
| 001  | Maths   | Apr 2 2017 | 

002和003没有什么

为004

| 004  | Science   | Mar 1 2017 | 
| 004  | Maths   | Apr 7 2017 | 

当我尝试应用逻辑我在here中提到,分区不起作用,因为学生可以再次回到同一个部门。请帮助。

+0

你所描述的和你所呈现的结果是不同的,这会造成混淆。 –

+0

@RameshKharbuja我正在尝试查找部门中用户首选项已更改的记录。请让我知道是什么造成混乱。 – Poppy

+1

对于学生1和4,结果中没有英文排行,尽管对于学生1和4而言数学和英语都有变化 –

回答

5

你可以使用LEAD窗函数 - SQL 2012及更高版本...

DECLARE @SampleData AS TABLE 
(
    Id int, 
    Department varchar(20), 
    [Date] date 
) 

INSERT INTO @SampleData 
VALUES (1,'English', 'Feb 3 2017'),(1,'English', 'Feb 4 2017'),(1,'Science', 'Mar 1 2017'), 
(1,'Maths', 'Mar 2 2017'),(1,'Maths', 'Mar 3 2017'),(1,'English', 'Mar 7 2017'), 
(2,'Maths', 'Feb 3 2017'),(2,'Maths', 'Feb 4 2017'), 
(3,'Maths', 'Feb 3 2017'), (3,'Maths', 'Feb 4 2017'), 
(4,'Science', 'Feb 1 2017'), (4,'Science', 'Feb 2 2017'), (4,'Maths', 'Feb 3 2017'),(4,'English', 'Feb 4 2017') 

;WITH temps AS 
(
    SELECT sd.*, LEAD(sd.Department, 1) OVER(PARTITION BY id ORDER BY sd.[Date]) AS NextDepartment 
    FROM @SampleData sd  
) 
SELECT t.id, t.Department,t.[Date] FROM temps t 
WHERE t.Department != t.NextDepartment 

演示链接:Rextester

参考链接:LEAD - MDSN

对于老版本,你可以使用OUTER APPLY

SELECT sd.* 
FROM @SampleData sd 
OUTER APPLY 
(
    SELECT TOP 1 * FROM @SampleData sd2 WHERE sd.Id = sd2.Id AND sd.[Date] < sd2.[Date] 
) nextDepartment 
WHERE sd.Department != nextDepartment.Department 
+0

中仅限于SQL Server 2012及更高版本。 –

+0

是的,我会注意到... – TriV

相关问题