如何在带WHERE子句的SQL查询中取最新时间记录?多表查询报错求助
解决SQL子查询返回多行的错误问题
首先,咱们来搞清楚你遇到的single-row subquery returns more than one row错误到底是咋回事:
你最后那个子查询select record_key from ro_main_table where serial_nr = 'Y39489'返回了不止一条记录——也就是说在你的RO_MAIN_TABLE里,同一个序列号Y39489对应了多个record_key值。而你用a.record_key = (子查询)这种写法时,数据库要求这个子查询必须恰好返回一行,所以就触发了错误。
接下来分两种场景给你解决方案:
场景1:一个序列号(serial_nr)应该只对应一个工单(record_key)
如果你的业务逻辑里,每个serial_nr本来就该唯一对应一个record_key,那问题出在数据上——可能RO_MAIN_TABLE里存在重复的serial_nr记录。你可以先排查清理重复数据,或者临时在子查询里加限制确保只返回一行:
select a.machine_status from ro_lamel_Data a inner join ( select record_key, max(pr_date_time) as MaxDate from ro_lamel_Data group by record_key ) b on a.record_key = b.record_key and a.pr_date_time = b.MaxDate where a.record_key = ( select record_key from ro_main_table where serial_nr = 'Y39489' limit 1 -- 强制只取第一条匹配的记录,或者用DISTINCT去重 );
不过更建议你先核查RO_MAIN_TABLE的数据,把重复的serial_nr记录处理掉,避免后续再出问题。
场景2:一个序列号(serial_nr)确实对应多个工单(record_key)
如果业务上允许一个序列号对应多个工单批次,那你只需要把主查询里的=改成IN,这样就能匹配多个record_key,同时获取每个工单对应的最新机器状态:
select a.machine_status, a.record_key -- 可以加上record_key,区分不同工单的状态 from ro_lamel_Data a inner join ( select record_key, max(pr_date_time) as MaxDate from ro_lamel_Data group by record_key ) b on a.record_key = b.record_key and a.pr_date_time = b.MaxDate where a.record_key IN ( select record_key from ro_main_table where serial_nr = 'Y39489' );
更简洁的方案:用窗口函数实现
其实还有更现代、可读性更强的写法,用窗口函数ROW_NUMBER()来直接标记每个record_key的最新记录,逻辑更清晰:
WITH latest_lamel AS ( SELECT machine_status, record_key, -- 按record_key分组,每条记录按时间倒序排,最新的那条标记为1 ROW_NUMBER() OVER (PARTITION BY record_key ORDER BY pr_date_time DESC) AS rn FROM ro_lamel_Data ) SELECT ll.machine_status, ll.record_key FROM latest_lamel ll JOIN ro_main_table mt ON ll.record_key = mt.record_key WHERE mt.serial_nr = 'Y39489' AND ll.rn = 1; -- 只取每个record_key的最新记录
这种写法不管serial_nr对应多少个record_key,都能准确返回每个工单的最新机器状态,而且后续维护起来也更方便。
内容的提问来源于stack exchange,提问作者Eda
相关产品推荐
相关产品推荐

