难以加入 (SQL)

Difficult join (SQL)

我有2个sql数据集:

数据集1:

select * from (
       Select 1 rn, 'b' c, 3 Val from dual  UNION ALL
       Select 1 rn, 'r' c, 3 Val from dual  UNION ALL
       Select 1 rn, 'w' c, 3 Val from dual  UNION ALL
       Select 2 rn, 'b' c, 2 Val from dual  UNION ALL
       Select 2 rn, 'r' c, 2 Val from dual  UNION ALL
       Select 3 rn, 'b' c, 1 Val from dual  

) t1

数据集2:

select * from ( 
       Select 'b' c from dual  UNION ALL
       Select 'r' c from dual  UNION ALL
       Select 'w' c from dual ) t2
   

我需要获取以下数据集:

rn  c   val
1   b   3 
1   r   3 
1   w   3 
2   b   2 
2   r   2 
2   w   null 
3   b   1 
3   r   null 
3   w   null

我尝试使用以下 sql 执行此操作,但它不起作用。

select t1.*, t2.*
FROM (
       Select 1 rn, 'b' c, 3 Val from dual  UNION ALL
       Select 1 rn, 'r' c, 3 Val from dual  UNION ALL
       Select 1 rn, 'w' c, 3 Val from dual  UNION ALL
       Select 2 rn, 'b' c, 2 Val from dual  UNION ALL
       Select 2 rn, 'r' c, 2 Val from dual  UNION ALL
       Select 3 rn, 'b' c, 1 Val from dual  

) t1 right join ( 
       Select 'b' c from dual  UNION ALL
       Select 'r' c from dual  UNION ALL
       Select 'w' c from dual ) t2 on   t1.c=t2.c 
       order by 1,2
   

请帮我解决我的问题。我使用 Oracle 数据库。

在这两个表之间交叉连接的一点帮助下(这样你就可以获得所有 [rn, c] 组合;那是我的 temp CTE),然后将其外连接到 t1,你会得到结果。

第 1 - 14 行中的示例数据;您可能感兴趣的查询从第 15 行开始(只需在其前面加上 WITH 关键字):

SQL> with t1 as (
  2         Select 1 rn, 'b' c, 3 Val from dual  UNION ALL
  3         Select 1 rn, 'r' c, 3 Val from dual  UNION ALL
  4         Select 1 rn, 'w' c, 3 Val from dual  UNION ALL
  5         Select 2 rn, 'b' c, 2 Val from dual  UNION ALL
  6         Select 2 rn, 'r' c, 2 Val from dual  UNION ALL
  7         Select 3 rn, 'b' c, 1 Val from dual
  8  ),
  9  t2 as (
 10         Select 'b' c from dual  UNION ALL
 11         Select 'r' c from dual  UNION ALL
 12         Select 'w' c from dual
 13  ),
 14  --

 15  temp as
 16    (select distinct a.rn, b.c
 17     from t1 a cross join t2 b
 18    )
 19  select t.rn, t.c, a.val
 20  from temp t left join t1 a on a.rn = t.rn and a.c = t.c
 21  order by t.rn, t.c;

        RN C        VAL
---------- - ----------
         1 b          3
         1 r          3
         1 w          3
         2 b          2
         2 r          2
         2 w
         3 b          1
         3 r
         3 w

9 rows selected.

SQL>

这正是分区外连接的用例。对于大型数据集,它应该比 CROSS JOIN 方法更有效。

语法是这样的:

select t1.rn, 
       t2.c,
       t1.val
from   t1 partition by (rn) right join t2 on t2.c = t1.c;

PARTITION BY 关键字告诉 Oracle 为 t1.rn 的每个不同值重复外连接。

这是一个完整的例子:

with t1 as (
     Select 1 rn, 'b' c, 3 Val from dual  UNION ALL
     Select 1 rn, 'r' c, 3 Val from dual  UNION ALL
     Select 1 rn, 'w' c, 3 Val from dual  UNION ALL
     Select 2 rn, 'b' c, 2 Val from dual  UNION ALL
     Select 2 rn, 'r' c, 2 Val from dual  UNION ALL
     Select 3 rn, 'b' c, 1 Val from dual
  ),
  t2 as (
     Select 'b' c from dual  UNION ALL
     Select 'r' c from dual  UNION ALL
     Select 'w' c from dual
  )
 select t1.rn, 
        t2.c,
        t1.val
 from   t1 partition by (rn) right join t2 on t2.c = t1.c;
+----+---+-----+
| RN | C | VAL |
+----+---+-----+
|  1 | b |   3 |
|  1 | r |   3 |
|  1 | w |   3 |
|  2 | b |   2 |
|  2 | r |   2 |
|  2 | w |   - |
|  3 | b |   1 |
|  3 | r |   - |
|  3 | w |   - |
+----+---+-----+