Oracle SQL Self-Join:如何包括丢失的记录

时间:2018-11-19 04:19:20

标签: sql oracle

即使没有记录,我也要显示NAME和PLAN。我试图在此连接上使用自我连接,但没有运气:(

脚本:

    SELECT DISTINCT    A.NAME  , B.PLAN
    FROM PLAYER A  
    LEFT JOIN PLAYER B
    ON A.NAME = B.NAME 
    WHERE A.NAME IN ( 'BOGGIE', 'STEPH')
    AND  B.PLAN IN ('PLAN200' , 'PLAN999');

当前结果

    NAME    PLAN
    BOOGIE  PLAN200
    STEPH   PLAN200

预期结果

    NAME    PLAN
    BOOGIE  PLAN200
    BOOGIE  
    STEPH   PLAN200
    STEPH   

    NAME    PLAN    AMOUNT  CONTRACT
    BOGGIE  PLAN200   200      24
    STEPH   PLAN200   200      24

4 个答案:

答案 0 :(得分:2)

您可以尝试将其他条件放在List

ON clause

答案 1 :(得分:0)

查询的问题是:

A.NAME IN ( 'BOGGIE', 'STEPH') AND B.PLAN IN ('PLAN200' , 'PLAN999');

查询将left join放在NAME上,但是在应用left join之后,记录将被进一步过滤。应该在left join子句中正确添加where子句条件。

下面的查询应给出预期的结果。

SELECT DISTINCT    A.NAME  , B.PLAN
FROM PLAYER A 
LEFT JOIN PLAYER B
ON A.NAME = B.NAME
AND (A.NAME IN ( 'BOGGIE', 'STEPH')
OR B.PLAN IN ('PLAN200' , 'PLAN999'));

答案 2 :(得分:0)

问题中的样本数据不完整,无法获得所需的输出;请尝试以下。为BOGGIE和STEPH添加了两行,其中包含空计划;让我们知道这足够了。

WITH player
     AS (SELECT 'BOGGIE' name,
                'PLAN200' plan,
                200 amount,
                24 contract
           FROM DUAL
         UNION
         SELECT 'STEPH ' name,
                'PLAN200' plan,
                200 amount,
                24 contract
           FROM DUAL
         UNION
         SELECT 'BOGGIE' name,
                NULL plan,
                NULL amount,
                NULL contract
           FROM DUAL
         UNION
         SELECT 'STEPH ' name,
                NULL plan,
                NULL amount,
                NULL contract
           FROM DUAL)
SELECT DISTINCT a.name, b.plan
  FROM player a
       LEFT OUTER JOIN player b
          ON     a.name = b.name
             AND (   a.name IN ('BOGGIE', 'STEPH')
                  OR b.plan IN ('PLAN200', 'PLAN999')) 

输出

NAME   PLAN   
------ -------
BOGGIE PLAN200
BOGGIE        
STEPH  PLAN200
STEPH 

答案 3 :(得分:0)

首先通过两个计划交叉加入PLAYER-> cross_result。 一旦得到,结果集将如下所示

cross_result
BOOGIE PLAN200
BOOGIE PLAN999
STEPH  PLAN200
STEPH  PLAN999

player
BOOGIE PLAN200
STEPH  PLAN200

此后,将cross_result与PLAYER表连接起来

with cte
      as (SELECT 'PLAN200' as plan FROM DUAL
           UNION ALL
          SELECT 'PLAN999' as plan FROM DUAL
          )
    ,cross_result  
     as (select A.PLAYER,A.PLAN
           from cte m
           join PLAYER A
             ON A.NAME IN ( 'BOGGIE', 'STEPH')
         )
   select a.PLAYER,b.PLAN /*I have choosen b.PLAN, so for a.PLAN=PLAN99 it would display null*/
     from cross_result a
left join PLAYER b
       on a.player=b.player
      and a.plan=b.plan