Имитировать левое соединение без использования "левого соединения"

Мне нужно смоделировать эффект левого соединения без использования клавиши "левого соединения".

У меня есть две таблицы: A и B, как с столбцами id, так и name. Я хотел бы выбрать все dbids для обеих таблиц, где имя в равно имени в B.

Я использую это для синхронизации, поэтому в начале B пусто (поэтому у меня будут пары с id из A со значением, а id из B - null). Позже у меня будет сочетание пар со значением - значением и значением - null.

Обычно это будет:

SELECT A.id, B.id
FROM A left join B
ON A.name = B.name

Проблема заключается в том, что я не могу использовать left join и хотел бы знать, можно ли/как сделать то же самое.

Ответ 1

вы можете использовать этот подход, но вы должны быть уверены, что внутренний выбор возвращает только одну строку.

SELECT A.id, 
(select B.id from B where  A.name = B.name) as B_ID
FROM A 

Ответ 2

Просто отмените таблицы и используйте вместо них правое соединение.

SELECT A.id,
       B.id
FROM   B
       RIGHT JOIN A
         ON A.name = B.name  

Ответ 3

Я не знаком с java/jpa. Используя чистый SQL, здесь один подход:

SELECT A.id AS A_id, B.id AS B_id
  FROM A INNER JOIN B
          ON A.name = B.name
UNION
SELECT id AS A_id, NULL AS B_id 
  FROM A 
 WHERE name NOT IN ( SELECT name FROM B );

Ответ 4

В SQL Server, например, вы можете использовать оператор *= для создания левого соединения:

select A.id, B.id
from A, B
where A.name *= B.name

Другие базы данных могут иметь несколько иной синтаксис, если такой оператор существует вообще.

Это старый синтаксис, используемый перед ключевым словом join. Разумеется, если это возможно, используйте ключевое слово join. Старый синтаксис может даже не работать в более новых версиях базы данных.

Ответ 5

Вы можете использовать подзапросы, например:

select a.id
,      nvl((select b.id from b where b.name = a.name), "") as bId
from a

Ответ 6

Я могу думать только о двух путях, которые до сих пор не были даны. Мои последние три идеи уже были даны (boohoo), но я поместил их здесь для потомков. Я ДУМАЛ о них без обмана. : -p

  1. Вычислите, есть ли у B совпадение, затем предоставьте дополнительную UNIONed строку для набора B, чтобы предоставить NULL, когда нет совпадения.

    SELECT A.Id, A.Something, B.Id, B.Whatever, B.SomethingElse
    FROM
       (
          SELECT
             A.*,
             CASE
                WHEN EXISTS (SELECT * FROM B WHERE A.Id = B.Id) THEN 1
                ELSE 0
             END Which
          FROM A
       ) A
       INNER JOIN (
          SELECT 1 Which, B.* FROM B
          UNION ALL SELECT 0, B* FROM B WHERE 1 = 0
       ) B ON A.Which = B.Which
          AND (
             A.Which = 0
             OR (
                A.Which = 1
                AND A.Id = b.Id
             )
          )
    
  2. Немного другой взгляд на тот же запрос:

    SELECT A.Id, B.Id
    FROM
       (
          SELECT
             A.*,
             CASE
                WHEN EXISTS (SELECT * FROM B WHERE A.Id = B.Id) THEN A.Id
                ELSE -1 // a value that doesn't exist in B
             END PseudoId
          FROM A
       ) A
       INNER JOIN (
          SELECT B.Id PseudoId, B.Id FROM B
          UNION ALL SELECT -1, NULL
       ) B ON A.Which = B.Which
          AND A.PseudoId = B.PseudoId
    
  3. Только для SQL Server специально. Я знаю, это действительно левое соединение, но это не говорит LEFT там!

    SELECT A.Id, B.Id
    FROM
       A
       OUTER APPLY (
          SELECT *
          FROM B
          WHERE A.Id = B.Id
       ) B
    
  4. Получите внутреннее соединение, затем СОЕДИНИТЕ внешнее соединение:

    SELECT A.Id, B.Id
    FROM
       A
       INNER JOIN B ON A.name = B.name
    UNION ALL 
    SELECT A.Id, NULL
    FROM A
    WHERE NOT EXISTS (
       SELECT *
       FROM B
       WHERE A.Id = B.Id
    )
    
  5. Используйте ПРАВИЛЬНОЕ СОЕДИНЕНИЕ. Это не левое соединение!

    SELECT A.Id, B.Id
    FROM
       B
       RIGHT JOIN A ON B.name = A.name
    
  6. Просто выберите значение B в выражении подзапроса (пусть будет только один B на A). Несколько столбцов из B могут быть их собственными выражениями (YUCKO!):

    SELECT A.Id, (SELECT TOP 1 B.Id FROM B WHERE A.Id = B.Id) Bid
    FROM A
    

Любой, кто использует Oracle, может нуждаться в некоторых предложениях FROM DUAL в любых SELECT, которые не имеют FROM.

Ответ 7

вы можете использовать оператор oracle + для левого соединения: -

SELECT A.id, B.id ОТ А, В ON A.name = B.name(+)

Найти ссылку: -

Oracle "(+)" Оператор

Ответ 8

SELECT A.id, B.id
FROM A full outer join B
ON A.name = B.name
where A.name is not null

Ответ 9

Я не уверен, что вы просто не можете использовать LEFT JOIN, или если вам вообще запрещено использовать любой JOINS. Но насколько я понимаю ваши требования, INNER JOIN должен работать:

SELECT A.id, B.id
FROM A 
INNER JOIN B ON A.name = B.name

Ответ 10

Имитация левого соединения с использованием чистого простого SQL:

SELECT A.name
FROM A
where (select count(B.name) from B where  A.id = B.id)<1; 

В левом соединении нет строк в B, ссылающихся на A, поэтому 0 имен в B будут ссылаться на строки в A, у которых нет соответствия + или A.id = B.id в предложении where для имитации внутреннего соединения