Кто-нибудь использует Right Outer Joins? - PullRequest
35 голосов
/ 27 марта 2009

Я все время использую INNER JOIN и LEFT OUTER JOIN. Однако мне никогда не нужны ПРАВЫЕ НАРУЖНЫЕ СОЕДИНЕНИЯ.

Я видел множество неприятных автоматически сгенерированных SQL, которые используют правильные объединения, но для меня этот код невозможно обойти. Мне всегда нужно переписывать его, используя внутренние и левые соединения, чтобы сделать из него головы или хвосты.

Кто-нибудь на самом деле пишет запросы с использованием правых соединений?

Ответы [ 9 ]

25 голосов
/ 27 марта 2009

Зависит от того, на какую сторону объединения вы ставите каждую таблицу.

Если вы хотите вернуть все строки из левой таблицы, даже если в правой таблице нет совпадений ... используйте левое соединение.

Если вы хотите вернуть все строки из правой таблицы, даже если в левой таблице нет совпадений, используйте правое соединение.

Интересно, что я редко использовал правильные соединения.

24 голосов
/ 06 сентября 2011

Приведите один пример, где RIGHT JOIN может быть полезным.

Предположим, что есть три стола для людей, домашних животных и аксессуаров для домашних животных. Люди могут при желании иметь домашних животных, и эти домашние животные могут иметь дополнительные принадлежности

CREATE TABLE Persons
  (
     PersonName VARCHAR(10) PRIMARY KEY
  );

INSERT INTO Persons
VALUES      ('Alice'),
            ('Bob'),
            ('Charles');

CREATE TABLE Pets
  (
     PetName    VARCHAR(10) PRIMARY KEY,
     PersonName VARCHAR(10)
  );

INSERT INTO Pets
VALUES      ('Rover',
             'Alice'),
            ('Lassie',
             'Alice'),
            ('Fifi',
             'Charles');

CREATE TABLE PetAccessories
  (
     AccessoryName VARCHAR(10) PRIMARY KEY,
     PetName       VARCHAR(10)
  );

INSERT INTO PetAccessories
VALUES      ('Ball', 'Rover'),
            ('Bone', 'Rover'),
            ('Mouse','Fifi');

Если требуется получить результат, перечислив всех людей независимо от того, имеют ли они домашнее животное или нет, и информацию о любых принадлежащих им домашних животных, которые также имеют аксессуары.

Это не работает (исключая Боба)

SELECT P.PersonName,
       Pt.PetName,
       Pa.AccessoryName
FROM   Persons P
       LEFT JOIN Pets Pt
         ON P.PersonName = Pt.PersonName
       INNER JOIN PetAccessories Pa
         ON Pt.PetName = Pa.PetName; 

Это не работает (включает Ласси)

SELECT P.PersonName,
       Pt.PetName,
       Pa.AccessoryName
FROM   Persons P
       LEFT JOIN Pets Pt
         ON P.PersonName = Pt.PersonName
       LEFT JOIN PetAccessories Pa
         ON Pt.PetName = Pa.PetName; 

Этот действительно работает (но синтаксис понимается гораздо реже, так как для достижения требуемого порядка логического соединения требуются два предложения ON)

SELECT P.PersonName,
       Pt.PetName,
       Pa.AccessoryName
FROM   Persons P
       LEFT JOIN Pets Pt
                  INNER JOIN PetAccessories Pa
                    ON Pt.PetName = Pa.PetName
         ON P.PersonName = Pt.PersonName;

В целом, вероятно, проще всего использовать RIGHT JOIN

SELECT P.PersonName,
       Pt.PetName,
       Pa.AccessoryName
FROM   Pets Pt
       JOIN PetAccessories Pa
         ON Pt.PetName = Pa.PetName
       RIGHT JOIN Persons P
         ON P.PersonName = Pt.PersonName;

Хотя, если решено избежать этого, другим вариантом будет введение производной таблицы, которую можно оставить присоединенной к

SELECT P.PersonName,
       T.PetName,
       T.AccessoryName
FROM   Persons P
       LEFT JOIN (SELECT Pt.PetName,
                         Pa.AccessoryName,
                         Pt.PersonName
                  FROM   Pets Pt
                         JOIN PetAccessories Pa
                           ON Pt.PetName = Pa.PetName) T
         ON T.PersonName = P.PersonName; 

SQL-скрипты: MySQL , PostgreSQL , SQL Server

9 голосов
/ 27 марта 2009

Обычно вы используете ПРАВЫЕ ВНЕШНИЕ СОЕДИНЕНИЯ для поиска бесхозных предметов в других таблицах.

6 голосов
/ 27 марта 2009

Нет, я не по той простой причине, что могу выполнить все с помощью внутренних или левых соединений.

2 голосов
/ 27 марта 2009

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

* 1003 Т.е. *

Главное здесь

нужно больше мусора

Подробнее Junk right external join Main Stuff

Я предпочитаю делать основной материал, чем мусор ... Так что оставил для меня внешнюю работу.

Так что бы ни плыла твоя лодка.

2 голосов
/ 27 марта 2009

Единственный раз, когда я использую правое внешнее объединение, это когда я работаю над существующим запросом и мне нужно изменить его (обычно из внутреннего). Я мог бы отменить объединение и сделать его левым и, вероятно, все будет в порядке, но я стараюсь уменьшить количество вещей, которые я изменяю, когда я изменяю код.

1 голос
/ 27 марта 2009

Редко, как уже говорилось, вы обычно можете изменить порядок и использовать левое соединение. Кроме того, я, естественно, склоняюсь к упорядочению данных, чтобы левые соединения работали для получения необходимых мне данных. Я думаю, то же самое можно сказать и о полных внешних и перекрестных соединениях, большинство людей стремятся держаться от них подальше.

1 голос
/ 27 марта 2009

Вы можете сделать то же самое, используя левое или правое соединение. Как правило, большинство людей думают о левом соединении, вероятно, потому что мы читаем слева направо. Это действительно сводится к тому, чтобы быть последовательным. Ваша команда должна сосредоточиться на использовании ЛЕВЫХ или ПРАВИЛЬНЫХ объединений, а не обоих, поскольку они, по сути, представляют собой одну и ту же вещь, написанную по-разному.

1 голос
/ 27 марта 2009

Наша стандартная практика здесь состоит в том, чтобы писать все в терминах ЛЕВЫХ СОЕДИНЕНИЙ, если это возможно. Иногда мы использовали FULL OUTER JOINs, если это было необходимо, но никогда не использовали RIGHT JOINS.

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