PL/SQL Developer中如何按行并行合并两个表(非笛卡尔积)
如何并行合并两个表的对应行(避免笛卡尔积)
嘿,这个需求核心就是按行的位置进行一对一合并,而不是生成所有行的笛卡尔积对吧?在Oracle中,我们可以借助ROW_NUMBER()分析函数给每行分配唯一行号,再通过行号关联来实现。下面结合你的示例给出具体方案:
先准备示例数据
-- 创建并填充示例表1:Table1 CREATE TABLE Table1 (LongId NUMBER); INSERT INTO Table1 VALUES (100); INSERT INTO Table1 VALUES (200); INSERT INTO Table1 VALUES (300); -- 创建并填充示例表2:Table2 CREATE TABLE Table2 (Id NUMBER); INSERT INTO Table2 VALUES (1); INSERT INTO Table2 VALUES (2); INSERT INTO Table2 VALUES (3);
核心合并SQL(直接生成新表)
CREATE TABLE NewTable AS SELECT t2.Id, t1.LongId FROM ( -- 给Table1每行加行号 SELECT LongId, ROW_NUMBER() OVER (ORDER BY NULL) AS rn FROM Table1 ) t1 JOIN ( -- 给Table2每行加行号 SELECT Id, ROW_NUMBER() OVER (ORDER BY NULL) AS rn FROM Table2 ) t2 ON t1.rn = t2.rn;
关键逻辑解释
ROW_NUMBER() OVER (ORDER BY NULL):给每个表的每行分配递增的行号。这里ORDER BY NULL表示采用数据库默认的存储顺序取行,如果你的表有明确的排序规则(比如按某个字段排序后再合并),把NULL换成对应的字段即可,比如ORDER BY LongId或ORDER BY Id。- 通过行号
rn关联两个表,就能精准实现第1行和第1行合并、第2行和第2行合并,完全避免了笛卡尔积的问题。 - 执行后,
NewTable就会得到你想要的结果:Id LongId 1 100 2 200 3 300
处理行数不一致的情况
如果两个表的行数不一样,比如Table1有3行、Table2有4行,上面的JOIN只会返回行数较少的表的结果。如果想保留所有行(超出的行显示NULL),可以改用FULL OUTER JOIN:
CREATE TABLE NewTable AS SELECT t2.Id, t1.LongId FROM ( SELECT LongId, ROW_NUMBER() OVER (ORDER BY NULL) AS rn FROM Table1 ) t1 FULL OUTER JOIN ( SELECT Id, ROW_NUMBER() OVER (ORDER BY NULL) AS rn FROM Table2 ) t2 ON t1.rn = t2.rn;
内容的提问来源于stack exchange,提问作者John Merc




