Подтвердить что ты не робот

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

Я использую INNER JOIN и LEFT OUTER JOINs все время. Тем не менее, мне никогда не нравятся ПРАВЫЕ ВНЕШНИЕ СОБЫТИЯ.

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

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

4b9b3361

Ответ 1

Это зависит от того, на какой стороне соединения вы помещаете каждую таблицу.

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

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

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

Ответ 2

Чтобы привести один пример, где a 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; 

Этот не работает (включает Lassie)

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 Fiddles: MySQL, PostgreSQL, SQL Server

Ответ 3

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

Ответ 4

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

Ответ 5

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

Ответ 6

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

т.е.

Здесь главное здесь

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

Больше неаккуратного внешнего внешнего соединения. Основной материал

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

Итак, что бы ни плавало на вашей лодке.

Ответ 7

Наша стандартная практика заключается в том, чтобы написать все, что возможно, с помощью LEFT JOINs. Мы иногда использовали FULL OUTER JOINs, если нам это нужно, но никогда не ПРАВИЛЬНЫЕ СОЕДИНЕНИЯ.

Ответ 8

Вы можете выполнить одно и то же, используя комбинации LEFT или RIGHT. Обычно большинство людей думают с точки зрения ЛЕВОГО присоединения, вероятно, потому, что мы читаем слева направо. Это действительно сводится к тому, чтобы быть последовательным. Ваша команда должна сосредоточиться на использовании LEFT или RIGHT, а не обоих, поскольку они по сути являются одной и той же точной, написанной по-разному.

Ответ 9

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