Кто-нибудь использует правильные внешние соединения?
Я использую INNER JOIN и LEFT OUTER JOINs все время. Тем не менее, мне никогда не нравятся ПРАВЫЕ ВНЕШНИЕ СОБЫТИЯ.
Я видел много неприятного автоматического сгенерированного SQL, который использует правильные соединения, но для меня этот код невозможен. Мне всегда нужно переписать его, используя внутренние и левые соединения, чтобы сделать головы или хвосты.
Кто-нибудь действительно пишет запросы, используя правые соединения?
Ответы
Ответ 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
Редко, как указано, вы обычно можете изменить порядок и использовать левое соединение. Кроме того, я, естественно, стараюсь упорядочить данные, чтобы левые соединения работали для получения требуемых данных. Я думаю, что то же самое можно сказать о полных внешних и кросс-соединениях, большинство людей склонны держаться подальше от них.