2017-04-10 64 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

相關問題