跨库查询结果合并SQL优化及行数量匹配规则咨询
合并无关联表数据的SQL优化方案及疑问解答
嘿,你的需求我完全get到了——就是要把Alphabet表的ABCD列和Integers表的Numbers列,分别放到Excel的A、B列里对吧?先帮你指出原SQL的问题,再给你优化后的可行方案,顺便解答你关于行数的疑问~
原SQL的问题所在
你写的Create Table merged ( Select [ABCD] from [Alphabet] join with [Numbers] from [Integers])有两个核心问题:
- SQL语法里根本没有
join with这种写法,正确的连接需要明确关联条件或者指定连接类型 - 查询结构错误,没办法同时从两个表提取字段,直接执行肯定会报错
优化后的SQL写法
因为两个表没有天然的关联字段,我们需要给每行数据手动加上行号,通过行号来实现逐行匹配,这样就能得到你想要的A列对应ABCD、B列对应Numbers的结果。
场景1:两个表行数相等(比如你例子里的4行)
这种情况用内连接就能完美匹配,下面是不同数据库的可运行示例:
SQL Server / PostgreSQL
-- 如果需要创建表存储合并结果 CREATE TABLE merged AS SELECT a.ABCD, n.Numbers FROM ( -- 给Alphabet表的每行加行号,按ABCD排序(你也可以换成其他排序逻辑) SELECT ABCD, ROW_NUMBER() OVER (ORDER BY ABCD) AS row_num FROM Alphabet ) a JOIN ( -- 给Integers表的每行加行号,按Numbers排序 SELECT Numbers, ROW_NUMBER() OVER (ORDER BY Numbers) AS row_num FROM Integers ) n ON a.row_num = n.row_num; -- 如果只是要查询结果直接导出Excel,不需要建表,执行下面的语句就行 SELECT a.ABCD, n.Numbers FROM ( SELECT ABCD, ROW_NUMBER() OVER (ORDER BY ABCD) AS row_num FROM Alphabet ) a JOIN ( SELECT Numbers, ROW_NUMBER() OVER (ORDER BY Numbers) AS row_num FROM Integers ) n ON a.row_num = n.row_num;
MySQL 8.0+(支持窗口函数)
CREATE TABLE merged AS SELECT a.ABCD, n.Numbers FROM ( SELECT ABCD, ROW_NUMBER() OVER (ORDER BY ABCD) AS row_num FROM Alphabet ) a JOIN ( SELECT Numbers, ROW_NUMBER() OVER (ORDER BY Numbers) AS row_num FROM Integers ) n ON a.row_num = n.row_num;
场景2:两个表行数不等
如果两个表的行数不一样,用内连接会自动丢弃行数多的表中超出的部分。要是你想保留所有行,缺少的字段用NULL填充,可以用全外连接:
SELECT a.ABCD, n.Numbers FROM ( SELECT ABCD, ROW_NUMBER() OVER (ORDER BY ABCD) AS row_num FROM Alphabet ) a FULL OUTER JOIN ( SELECT Numbers, ROW_NUMBER() OVER (ORDER BY Numbers) AS row_num FROM Integers ) n ON a.row_num = n.row_num;
注意:MySQL不支持直接的
FULL OUTER JOIN,可以用LEFT JOIN+UNION模拟,写法如下:SELECT a.ABCD, n.Numbers FROM ( SELECT ABCD, ROW_NUMBER() OVER (ORDER BY ABCD) AS row_num FROM Alphabet ) a LEFT JOIN ( SELECT Numbers, ROW_NUMBER() OVER (ORDER BY Numbers) AS row_num FROM Integers ) n ON a.row_num = n.row_num UNION SELECT a.ABCD, n.Numbers FROM ( SELECT ABCD, ROW_NUMBER() OVER (ORDER BY ABCD) AS row_num FROM Alphabet ) a RIGHT JOIN ( SELECT Numbers, ROW_NUMBER() OVER (ORDER BY Numbers) AS row_num FROM Integers ) n ON a.row_num = n.row_num;
关于行数是否必须相等的疑问
完全不需要必须相等:
- 如果行数相等,内连接会完美匹配每一行,结果行数和原表一致
- 如果行数不等,用内连接会只保留到行数少的那个表的行数;用全外连接会保留所有行,缺少的字段显示
NULL - 你提到的27行只是其中一种相等的情况,实际不管两个表是多少行,都能通过上面的方法实现合并,只是结果行数会根据连接方式不同而变化
内容的提问来源于stack exchange,提问作者Ahmet
相关产品推荐
相关产品推荐

