如何筛选指定条件下按Component去重的最新时间数据行?
问题描述
现有数据表结构及数据如下:
| ID | ParentNumber | ObjectNumber | Start | Component | ... |
|---|---|---|---|---|---|
| 4b8cf664-0ef9-44b2-a266-6c27079b90ed | 2 | 1 | 2023-08-10T12:50:03.716000Z | 1 | ... |
| 92847bf9-dbfc-46ff-a9bb-b2210df66507 | 2 | 1 | 2023-08-11T17:13:30.716000Z | 1 | ... |
| fa9e0823-4432-480f-bbff-fbdac16a53fe | 2 | 1 | 2023-08-10T13:06:06.716000Z | 2 | ... |
| 9f3d4140-d8cc-4e01-8221-0991d2cc0ea4 | 2 | 1 | 2023-08-10T10:45:03.716000Z | 3 | ... |
| 02b70a62-77b7-4133-83a7-6c76d6cf7204 | 2 | 1 | 2023-08-12T09:26:22.716000Z | 3 | ... |
| 0cb48763-8bc1-4a10-8be4-721c8644dd94 | 2 | 1 | 2023-08-14T08:12:42.716000Z | 3 | ... |
需要筛选出ParentNumber = 2且ObjectNumber = 1的数据,按Component去重,仅保留每个Component对应Start时间最晚的完整条目,期望结果如下:
| ID | ParentNumber | ObjectNumber | Start | Component | ... |
|---|---|---|---|---|---|
| 92847bf9-dbfc-46ff-a9bb-b2210df66507 | 2 | 1 | 2023-08-11T17:13:30.716000Z | 1 | ... |
| fa9e0823-4432-480f-bbff-fbdac16a53fe | 2 | 1 | 2023-08-10T13:06:06.716000Z | 2 | ... |
| 0cb48763-8bc1-4a10-8be4-721c8644dd94 | 2 | 1 | 2023-08-14T08:12:42.716000Z | 3 | ... |
尝试过按Component分组,但无法获取完整的行数据,如何实现该查询?
解决方案
方法1:窗口函数(推荐,适配大多数现代数据库)
用ROW_NUMBER()窗口函数按Component分组,对Start降序排序后取每组第一条:
WITH ranked_data AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Component ORDER BY Start DESC) AS rn FROM your_table_name WHERE ParentNumber = 2 AND ObjectNumber = 1 ) SELECT ID, ParentNumber, ObjectNumber, Start, Component, ... FROM ranked_data WHERE rn = 1;
逻辑说明:
PARTITION BY Component:把数据按Component拆分成独立分组ORDER BY Start DESC:组内按时间从晚到早排序ROW_NUMBER()给每组记录标序号,最新的记录序号为1- 最后筛选序号为1的记录,就是每个
Component的最新完整条目
方法2:子查询关联(兼容旧版本数据库)
先查每个Component的最新Start时间,再关联原表拿完整数据:
SELECT t1.* FROM your_table_name t1 INNER JOIN ( SELECT Component, MAX(Start) AS latest_start FROM your_table_name WHERE ParentNumber = 2 AND ObjectNumber = 1 GROUP BY Component ) t2 ON t1.Component = t2.Component AND t1.Start = t2.latest_start WHERE t1.ParentNumber = 2 AND t1.ObjectNumber = 1;
注意:如果同一个Component有多个Start时间完全相同的记录,这个方法会返回所有匹配项。要仅留一条的话,可以结合窗口函数或加额外排序条件(比如按ID排序)。
方法3:LATERAL JOIN(适配PostgreSQL、SQL Server等)
通过LATERAL子查询逐个获取每个Component的最新记录:
SELECT t1.* FROM (SELECT DISTINCT Component FROM your_table_name WHERE ParentNumber=2 AND ObjectNumber=1) t2 LATERAL ( SELECT * FROM your_table_name t1 WHERE t1.Component = t2.Component AND t1.ParentNumber = 2 AND t1.ObjectNumber = 1 ORDER BY Start DESC LIMIT 1 ) t1;
逻辑说明:先提取所有符合条件的Component值,再针对每个Component查询其最新的一条完整记录。
内容的提问来源于stack exchange,提问作者sirzento
相关产品推荐
相关产品推荐

