一对二关系加入

时间:2016-08-29 15:36:40

标签: sql oracle join

在表-2中,每个T_CODE(AB& AC)应该有2个E_NO(55& 56)。

我想加入这两个表来显示所有T_CODE和E_NOs。如果在表2中不可用,则应显示NULL

表-1

T_NO    T_Code
1        AB
1        AC
2        AB
3        AB
3        AC
4        AC

表-2

T_NO    T_Code  E_NO
1         AB    55
1         AC    56
2         AB    55
3         AC    55
3         AC    56
3         AB    55
3         AB    56
4         AC    55

结果

T_NO    T_Code  E_NO
1         AB    55
1       **AB**  **56**
1         AC    56
1       (null)  (null) -> AC 55
2         AB    56
2       **AB**  **55**
3         AC    55
3         AC    56
3         AB    55
3         AB    56
4         AC    55
4       **AC**  **56**

你们可以帮我查询一下吗?

我尝试在table-1和table-2之间应用左外连接,但因为这是一对二关系所以对于表-2中不可用的记录不会出现NULL。

感谢Matt和Vercelli。

我正在尝试的另一件事是用缺少的字段填充(nulls)。我通过使用一些逻辑尝试使用PL-SQL但是有任何简单的方法可以做到这一点是我的问题。

3 个答案:

答案 0 :(得分:1)

使用辅助视图(aux)并与其交叉连接

with aux as (select 55 as e_no from dual
             union all
             select 56 as e_no from dual)
select t1.T_NO, t2.T_CODE, t2.E_NO
  from table1 t1 cross join aux a
                 left  join table2 t2 on t1.T_NO = t2.T_NO 
                                     and t1.T_CODE = t2.T_CODE 
                                     and a.E_NO = t2.E_NO;

答案 1 :(得分:1)

假设3& 4应该返回所有空值,因为没有匹配项:

WITH cteAllPossibleCombinations  AS (
    SELECT DISTINCT t.T_NO, c2.T_code, c.E_NO
    FROM
       Table1 t
       CROSS JOIN (SELECT 55 as E_NO from dual UNION SELECT 56 from dual) c
       CROSS JOIN (SELECT 'AB' as T_code from dual UNION SELECT 'AC' from dual) c2
)

SELECT
    c.T_NO
    ,t.T_Code
    ,t.E_NO
FROM
    cteAllPossibleCombinations c
    LEFT JOIN Table2 t
    ON c.T_NO = t.T_NO
    AND c.T_code = t.T_Code
    AND c.E_NO = t.E_NO

此答案处理表1中缺少“AB”或“AC”的情况。

根据您的评论进行编辑。所以我仍然不清楚你想填写的是什么。如果您不想区分它是否存在,只想要所有可能的组合,请忘记上面的第二个选择,然后选择。

SELECT * FROM cteAllPossibleCombinations

如果您想要区分匹配的内容而不是某些内容,那么这里的查询可能有助于您理解:

SELECT
    c.T_NO
    ,COALESCE(t.T_Code,'**' + c.T_Code) AS T_Code
    ,COALESCE(CAST(t.E_NO AS VARCHAR(10)),CAST(c.E_NO AS VARCHAR(10)) + '**') as E_No
    ,CASE WHEN t.T_Code IS NULL THEN 'NO' ELSE 'yes' END as Matched
FROM
    cteAllPossibleCombinations c
    LEFT JOIN @Table2 t
    ON c.T_NO = t.T_NO
    AND c.T_code = t.T_Code
    AND c.E_NO = t.E_NO

请注意,后面的代码都需要CTE。

答案 2 :(得分:0)

你走了:

SELECT C.E_NO, C.T_CODE, T2.T_NO
FROM (  
   SELECT E_NO.E_NO, T_CODE.T_CODE
   FROM ( VALUES (55), (56) ) AS E_NO(E_NO), 
        ( VALUES ('AB'), ('AC') ) AS T_CODE(T_CODE)
) AS C
LEFT JOIN Table-2 AS T2 ON (C.E_NO, C.T_CODE) = (T2.E_NO, T2.T_CODE)

这将为您提供具有值的T2.T_NO。如果你想插入遗漏的那些,那么只需使用上面的查询,而是添加WHERE T2.T_NO is null,你就会得到"缺少"的列表。的。

相关问题