【问题标题】:How to find the changes in records in SQL server如何在 SQL Server 中查找记录的更改
【发布时间】:2017-04-10 15:29:29
【问题描述】:

我有一张保存学生信息的表格。

+==========================================+
| 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 中提到的逻辑时,分区不起作用,因为学生可以再次回到同一个部门。请帮忙。

【问题讨论】:

  • 你所描述的和你呈现的结果是不同的,这会造成混乱。
  • @RameshKharbuja 我正在尝试查找部门中用户偏好发生变化的记录。请让我知道造成混乱的原因。
  • 学生 1 和 4 的结果中没有英语行,尽管学生 1 和 4 的数学都改为英语
  • 为什么 ID 004 记录在输出中跳过,他在 4 月 9 日将他的部门从数学改为英语?
  • @RameshKharbuja 。考虑到用户 1,他的偏好已从英语 - 科学更改,日期为 2 月 4 日。同样,从科学数学变为 3 月 1 日,他的偏好继续为数学,直到 4 月 2 日,之后他更改为英语。所以示例结果显示了上面给出的 3 行。

标签: sql sql-server


【解决方案1】:

您可以使用 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

【讨论】:

  • 仅限 SQL Server 2012 及更高版本。
猜你喜欢
  • 1970-01-01
  • 2013-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
相关资源
最近更新 更多