SQL关联AB两表按原始行序匹配值返回对应行号方案咨询
解决方法
首先明确核心逻辑:SQL表不存在默认的“原始行顺序”,你之前的写法出现行号错误,是因为窗口函数的ORDER BY指定了同分区内完全相同的ReportDate作为排序依据,数据库无法确定行的先后,返回的行号是随机的。
要实现需求,你需要先找到能确定Table B行先后顺序的依据,最稳妥的方案是表内有自增ID、插入时间戳这类随数据插入单调递增的字段,我们假设该字段名为auto_id,正确的查询语句如下:
SELECT a.ReportDate, a.val1, b.row_pos AS Match FROM TableA a LEFT JOIN ( SELECT ReportDate, val2, -- 同日期内按自增ID排序生成行号,和插入顺序一致 ROW_NUMBER() OVER (PARTITION BY ReportDate ORDER BY auto_id ASC) AS row_pos FROM TableB ) b ON a.ReportDate = b.ReportDate AND a.val1 = b.val2 ORDER BY a.ReportDate DESC;
如果Table B没有显式的排序字段,可以用对应数据库的内置伪列临时实现:
- Oracle 数据库使用
ROWID伪列:将上方窗口函数的排序规则改为ORDER BY ROWID ASC - PostgreSQL 数据库使用
ctid伪列:将上方窗口函数的排序规则改为ORDER BY ctid ASC - MySQL 数据库无通用伪列,若你使用MyISAM引擎,可尝试
ORDER BY (SELECT 1)获取物理存储顺序,InnoDB引擎建议优先补充自增主键字段。
注意:伪列生成的行号仅保证查询当时的物理存储顺序,若表有过删除、数据迁移、碎片整理等操作,会和你预期的插入顺序不一致,长期使用建议给Table B增加自增主键字段作为排序依据。
内容的提问来源于stack exchange,提问作者Bha123
相关产品推荐
相关产品推荐

