Oracle SQL Self-Join: как включить отсутствующую запись - PullRequest
0 голосов
/ 19 ноября 2018

Я хочу отобразить ИМЯ и ПЛАН, даже если они не являются записями. Я попытался использовать самосоединение, но безуспешно: (

сценарий:

    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 голосов
/ 19 ноября 2018

Первый крест соедините ИГРОКА с двумя планами -> 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
0 голосов
/ 19 ноября 2018

Проблема с запросом:

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

Запрос помещает left join в NAME, но записи подвергаются дальнейшей фильтрации после left joinбыл применен.Условия предложения where должны быть правильно добавлены в предложение left join.

В приведенном ниже запросе должен быть получен ожидаемый результат.

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'));
0 голосов
/ 19 ноября 2018

Пример данных в вопросе неполный, чтобы получить желаемый результат; пожалуйста, попробуйте ниже. Добавлены две строки для 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 
0 голосов
/ 19 ноября 2018

Вы можете попробовать ввести другое условие в ON clause

SELECT DISTINCT    A.NAME  , B.PLAN
    FROM PLAYER A  
    LEFT JOIN PLAYER B
    ON A.NAME = B.NAME 
    and A.NAME IN ( 'BOGGIE', 'STEPH')
    AND  B.PLAN IN ('PLAN200' , 'PLAN999');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...