加入仅在SQL中存在记录时起作用

时间:2019-04-27 10:16:58

标签: sql oracle

我有2个表-table1和table2。

在table2中,基于以下条件,table1有多个记录匹配条件:

c_type,h_level,循环,e_id

仅当存在完全匹配1时,我才希望从RIGHT表中进行记录。如果不是,那么element_nm应该为NULL,因此我在输出中的记录与左表完全相同。

SELECT   a.*,
         b.element_nm
FROM     table1 a
   LEFT JOIN table2 b ON
         a.c_type = b.c_type
   AND   a.h_level = b.h_level
   AND   a.loop = b.loop
   AND   a.e_id = b.e_id
ORDER BY a.file_name,
         a.line_num asc;

3 个答案:

答案 0 :(得分:2)

由于这仅是一个值,因此可以在select子句中使用Sub查询。否则,您将在LEFT OUTER JOIN中使用子查询或使用OUTER APPLY

SELECT 
  t1.*,
  (
    SELECT MIN(t2.element_nm)
    FROM table2 t2
    WHERE t2.c_type = t1.c_type
      AND t2.h_level = t1.h_level
      AND t2.loop = t1.loop
      AND t2.e_id = t1.e_id
    HAVING COUNT(*) = 1
  ) AS element_nm
FROM table1 t1
ORDER BY t1.file_name, t1.line_num;

答案 1 :(得分:2)

当您只希望第二张表中的一列时,Thorsten的答案有效。但是,如果您想要多列,则有点麻烦。

或者:

SELECT a.*, b.*
FROM table1 a LEFT JOIN
     (SELECT b.*,
             COUNT(*) OVER (PARTITION BY b.c_type, b.h_level, b.loop, b.e_id) as cnt
      FROM b
     ) b
     ON a.c_type = b.c_type AND
        a.h_level = b.h_level AND
        a.loop = b.loop AND
        a.e_id = b.e_id AND
        b.cnt = 1
ORDER BY a.file_name, a.line_num asc;

答案 2 :(得分:0)

您应该使用Row_Number,如下所示:

WITH cte AS (
SELECT ROW_NUMBER() OVER(PARTITION BY a.c_type ,a.h_level,a.loop  ,a.e_id   ) rnum
 ,a.c_type ,a.h_level,a.loop  ,a.e_id FROM     table1 a
   LEFT JOIN table2 b ON  a.c_type = b.c_type  AND  a.h_level = b.h_level  AND a.loop = b.loop AND a.e_id = b.e_id
) 
,cte2 AS (SELECT * FROM cte WHERE rnum = 2)
         SELECT   a.*,
  CASE WHEN cte2.element_nm IS NULL then       b.element_nm ELSE NULL END element_nm
FROM     table1 a
   LEFT JOIN table2 b ON  a.c_type = b.c_type  AND  a.h_level = b.h_level  AND a.loop = b.loop AND a.e_id = b.e_id
   LEFT JOIN cte2 ON    a.c_type = cte2.c_type AND  a.h_level = cte2.h_level AND a.loop = cte2.loop AND a.e_id = cte2.e_id