使用行号获取最新记录的记录,使用连接获取分区

Posted

技术标签:

【中文标题】使用行号获取最新记录的记录,使用连接获取分区【英文标题】:Get records with latest record using row number and partition using joins 【发布时间】:2020-07-26 07:33:09 【问题描述】:

这是我的 SQL Server 表:

 DECLARE @EMP TABLE
    (
        Id INT,
        NAME VARCHAR(200),
        AlarmOnTimeStamp DATETIMEOFFSET,
        AlarmOffTimeStamp DATETIMEOFFSET NULL
    );

DECLARE @EMPCOMMENT TABLE
(
    EmpId INT,
    Comment VARCHAR(2000)
)

INSERT INTO @EMP VALUES (1121, 'Test1', '2020-04-09 01:56:29.507', NULL)
INSERT INTO @EMP VALUES (57, 'Test1', '2020-04-09 02:56:29.507', NULL)
INSERT INTO @EMP VALUES (992, 'Test2', '2020-04-09 01:56:29.507', '2020-04-09 03:56:29.507')

INSERT INTO @EMPCOMMENT VALUES (2, 'Test1')
INSERT INTO @EMPCOMMENT VALUES (2, 'Test2')

SELECT *
FROM @emp e
LEFT JOIN @EMPCOMMENT ec ON ec.Id = e.Id

SELECT
    *,
    rn = ROW_NUMBER() OVER (PARTITION BY e.Name ORDER BY AlarmOnTimeStamp, e.Name DESC) 
FROM @emp e
LEFT JOIN @EMPCOMMENT ec ON e.Id = ec.EmpId

enter image description here

输出:

  Id      Name      AlarmOnTimeStamp           AlarmOffTimeStamp      EmpId     Comment    rn
  --------------------------------------------------------------------------------------------
  2       Test1      2020-04-09 02:56:29         NULL                  2          Good      1
  2       Test1      2020-04-09 02:56:29         NULL                  2          Best      1
  3       Test2      2020-04-09 01:56:29  2020-04-09 03:56:29.50       NULL       NULL      1

我只想要上面的结果

如果您在屏幕截图中看到第一条记录显示被删除,原因是它是一条旧记录,我只是想如果员工姓名相同,则获取其最新记录及其所有评论

【问题讨论】:

【参考方案1】:

我认为你想要:

SELECT *
FROM (
    SELECT *, RANK() OVER(PARTITION BY e.Name ORDER BY e.AlarmOnTimeStamp desc) rn
    FROM @emp e
    LEFT JOIN @EMPCOMMENT ec ON ec.EmpId = e.Id
) t
WHERE rn = 1

这会按 id 降序排列具有相同员工姓名的行,并仅保留最上面的行(包括关系)。

对于您的示例数据,the query yields

身份证 |姓名 | AlarmOnTimeStamp | AlarmOffTimeStamp |员工 ID |评论 | rn -: | :---- | :---------------------------- | :---------------------------- | ----: | :-------- | :- 2 |测试1 | 2020-04-09 02:56:29.5070000 | | 2 |测试1 | 1 2 |测试1 | 2020-04-09 02:56:29.5070000 | | 2 |测试2 | 1 3 |测试2 | 2020-04-09 01:56:29.5070000 | 2020-04-09 03:56:29.5070000 | | | 1

【讨论】:

谢谢,但是有没有更好的方法来代替按 e.id 订购,因为我刚刚给出了一个例子,这个 Id 列可以是唯一标识符,这就是为什么我必须依赖名称和AlarmOnTimeStamp 列 @t-bolt: 当然,您可以使用AlarmOnTimeStamp 订购。我调整了查询​​。

以上是关于使用行号获取最新记录的记录,使用连接获取分区的主要内容,如果未能解决你的问题,请参考以下文章

MYSQL Join - 父子表连接,只获取子表的最新记录

如何使用python获取丢失的记录行号和列名?

如何在 SQL 中以高性能的方式使用 PARTITION BY 获取最新记录?

左外连接获取所有行?

如何获取发生错误的行号,而不是从 Django 中记录错误的行号

在 MS Access 上返回行号