SQL查询du_vertrag表获取每个id各状态首次变更日期
解决方案
你可以通过两种通用SQL写法实现du_vertrag表按id+status配对去重、保留最早日期记录的需求,根据你使用的数据库版本选择即可:
- 窗口函数写法(推荐,支持MySQL 8.0+、PostgreSQL、SQL Server、BigQuery等所有支持SQL:2003标准的数据库)
逻辑是通过窗口函数给每个id+status分组内的记录按日期升序打行号,只取行号为1的首条记录,即使同组内有相同最小日期的记录,也只会固定返回一条,不会出现额外重复。
SELECT id, status, date FROM ( SELECT id, status, date, ROW_NUMBER() OVER (PARTITION BY id, status ORDER BY date ASC) AS row_num FROM du_vertrag ) AS ranked WHERE row_num = 1;
- 聚合关联写法(兼容不支持窗口函数的旧版本数据库,比如MySQL 5.x)
逻辑是先聚合算出每个id+status分组对应的最小日期,再关联原表取出对应完整记录。注意如果同个分组下有多条记录的date等于最小日期,这种写法会把这些记录全部返回。
SELECT d.id, d.status, d.date FROM du_vertrag AS d INNER JOIN ( SELECT id, status, MIN(date) AS first_date FROM du_vertrag GROUP BY id, status ) AS first_record ON d.id = first_record.id AND d.status = first_record.status AND d.date = first_record.first_date;
效果验证:以你提到的id=6251899、status=übergabe的两条测试数据为例,上述两种写法都会过滤掉20201010的晚日期记录,仅保留20201009的首条状态记录,符合预期。
性能优化建议:如果表数据量较大,可以给(id, status, date)三个字段建立联合索引,能大幅提升查询速度。
内容的提问来源于stack exchange,提问作者Anthony Admin
相关产品推荐
相关产品推荐

