Informix SQL 11.5:如何按列将两个查询结果按指定方式组合?
解决两个结果集按行位置一一匹配的问题
嘿,这个需求我之前也碰到过!本质上是要把两个结果集按行的位置一一匹配,也就是所谓的「位置连接」——UNION是用来合并同结构的数据集,JOIN是靠字段值关联,确实都满足不了你的需求。
核心思路
给两个查询的每一行都分配一个唯一的行号(按结果输出的顺序),然后通过行号将两个结果集做关联,就能实现table2的第n行对应table1的第n行的效果。
主流数据库写法(支持窗口函数:MySQL 8.0+、PostgreSQL、Oracle、SQL Server等)
我们可以用ROW_NUMBER()窗口函数给每个结果集生成行号,再通过行号做INNER JOIN:
SELECT t2.m2, t1.c1, t1.c2, t1.c3 FROM ( -- 给查询1的结果加行号 SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS row_num, c1, c2, c3 FROM table1 WHERE cond1 ) t1 INNER JOIN ( -- 给查询2的结果加行号 SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS row_num, m2 FROM table2 WHERE cond2 ) t2 ON t1.row_num = t2.row_num
注意点:
ORDER BY (SELECT NULL)是为了保持原查询的输出顺序,如果你的原查询有明确的排序字段(比如table1是按c1排序的),最好替换成对应的字段(比如ORDER BY c1),这样行号的顺序更可靠。- 如果两个结果集的行数不一致,
INNER JOIN只会保留行数匹配的行;如果需要保留所有行(哪怕某一边没有对应行),可以改用FULL JOIN,并处理NULL值。
老版本MySQL(5.x及以下,不支持窗口函数)
如果你的MySQL版本比较老,没法用ROW_NUMBER(),可以用用户变量来生成行号:
SELECT t2.m2, t1.c1, t1.c2, t1.c3 FROM ( -- 用变量生成查询1的行号 SELECT @row1 := @row1 + 1 AS row_num, c1, c2, c3 FROM table1, (SELECT @row1 := 0) r WHERE cond1 ORDER BY (SELECT NULL) ) t1 INNER JOIN ( -- 用变量生成查询2的行号 SELECT @row2 := @row2 + 1 AS row_num, m2 FROM table2, (SELECT @row2 := 0) r WHERE cond2 ORDER BY (SELECT NULL) ) t2 ON t1.row_num = t2.row_num
这个写法的原理是初始化一个变量,每读取一行就把变量加1,以此生成连续的行号。
内容的提问来源于stack exchange,提问作者MD128
相关产品推荐
相关产品推荐

