Причина віддати перевагу ПРАВИМУ ПРИЄДНАЙТЕСЬ перед ЛІВОМУ ПРИЄДНАЙТЕСЬ


18

Якщо я правильно розумію, кожен RIGHT JOIN:

SELECT Persons.*, Orders.*
FROM Orders
RIGHT JOIN Persons ON Orders.PersonID = Persons.ID

можна виразити як LEFT JOIN:

SELECT Persons.*, Orders.*
FROM Persons
LEFT JOIN Orders ON Persons.ID = Orders.PersonID

Моя особиста думка полягає в тому, що наміром заяви є:

  • Спочатку дістаньте Persons
  • Потім розгорніть / повторіть, Personsяк потрібно, щоб відповідатиOrders

краще виражається в порядку, Persons LEFT JOIN Ordersніж у зворотному порядку Orders RIGHT JOIN Persons(а я ніколи не використовую RIGHT JOINв результаті).

Чи є якісь ситуації, коли RIGHT JOINперевагу а? Або чи є випадки використання, коли RIGHT JOINможна зробити щось, що LEFT JOINне може?


12
Я не можу пригадати жодного випадку, коли я хотів право приєднатися У мене були випадки, коли план виконання запиту перевернув ліве з'єднання навколо правого з’єднання з міркувань продуктивності. Але з точки зору написання чистого коду, ні, я не пригадую, щоб коли-небудь писати правильне приєднання.
Брендон

2
Я не розглядаю це як питання про "пояснення, запис чи налагодження коду". Це питання, чому мова має дві особливості, які, мабуть, роблять те саме, якщо між ними насправді є якась різниця, а якщо ні, то коли буде віддано перевагу "неочевидному".
Філіп Кендалл

1
Ні, приєднання зліва майже завжди фіксує те, що вам потрібно найчастіше, і про це легше міркувати. На моєму робочому місці у нас фактично є стандарт, який запобігає правильним з'єднанням, оскільки ніколи не існує випадків, коли вони необхідні (тобто їх завжди можна замінити на протилежне ліве з'єднання).
mgw854

8
Я перезавантажив тісні голоси - це питання тут є темою, оскільки розуміння різниці між об'єднаннями впливає на розробку програмного забезпечення (дизайн бази даних є частиною дизайну програмного забезпечення, як і алгоритми, які можуть запитувати бази даних). Це може бути тематично у адміністраторів баз даних , і там може бути і дублікат.
Томас Оуенс

1
Я не впевнений, якщо ви припускаєте, що RIGHT JOINце рекомендується чи більше. Якщо це ваше приміщення, це неправильно. Я не можу придумати час, коли я бачив правильне з'єднання, яке використовується ні в коді, ні в прикладах. Це JOINабо LEFT OUTER JOIN. У рідкісних випадках ви можете побачити FULL OUTER JOIN.
JimmyJames

Відповіді:


12

Це залежить від того, яку вимогу ви намагаєтеся виконати.

Не те саме сказати: "дайте всі особи та їх відповідні накази", що "я хочу всіх замовлень з відповідними особами" , особливо якщо ви збираєтесь використовувати is nullрядки без відповідності. Це те, що я називаю "домінуючою таблицею", що є таблицею, з якої я хочу отримати рядки, незалежно від того, що в іншій частині з'єднання не існує відповідного рядка.

Подивіться на ці зображення, і ви помітите, що вони не однакові:

введіть тут опис зображення

Джерело зображення - це відмінна стаття .

Але ви маєте рацію в тому, що обидві вимоги можуть бути виконані з будь-яким об'єднанням, просто перевернувши порядок таблиць в з'єднанні.

Але я здогадуюсь, що для західних людей, звикли писати зліва направо, більш природно використовувати ліві з'єднання над правими з'єднаннями , оскільки ми бачимо, що ми хочемо, щоб з'єднання були в тому ж напрямку або в тому ж порядку, що іselect колонки Ed.

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

Деякі лінгвісти вважають, що ваша мова впливає на ваш спосіб мислення: https://www.edge.org/conversation/lera_boroditsky-how-does-our-language-shape-the-way-we-think


1
Я почав міркувати за цими напрямками, але не думаю, що це правильно. Я почав уявляти, як писати SQL на івриті (чого я ніколи не робив). ОК: справа виправдана, справа наліво, зверху вниз. Ви все ще згадаєте таблицю A спочатку та таблицю B. При правій приєднанні ви виключаєте (особливо в нульовому випадку) більшість або всю таблицю, згадану спочатку. Я думаю, що людський розум, як правило, асоціюється спочатку з первинним і найважливішим . Це відбувається незалежно від напрямку написання. Ви можете назвати їх "ПЕРШИЙ ПРИЄДНАЙТЕСЬ" та "ДРУГИЙ ПРИЄДНАЙТЕСЬ", і ця упередженість все-таки матиме місце.
Майк підтримує Моніку

Я включив посилання на зображення, яке ви показали нижче.
Джон Рейнор

@Mike Я не пропоную людям писати SQL арабською або івритом. Тільки те, що, можливо, орієнтація на вашу рідну мову може стати причиною того, що ви віддаєте перевагу правильним приєднанням. Але це лише можливість. Я вважаю, що ліві приєднання є більш природними.
Tulains Córdova

Тепер я віддав належну заслугу творцю образу. Я мав це роками у своєму HD, і я не пам’ятав, звідки він
узявся

Я вільно володію івритом і все ще вважаю LEFT JOINбільш природним.
Зев Шпіц

3

Немає нічого (що я знаю), що можна зробити за допомогою правого з'єднання, що неможливо зробити з лівим з'єднанням. Але іноді синтаксис з лівим приєднанням більш потворний. Скажімо, у вас є такі таблиці:

Persons
ID | Name

Orders
ID | CustomerId | other unimportant stuff

SpecialOrderDetails
ID | OrderId | other stuff

Скажімо, вам потрібно отримати список усіх людей у ​​вашій базі даних та будь-яких замовлень, які вони мають із спеціальними реквізитами замовлення (ми скажемо, що не всі замовлення мають спеціальні реквізити замовлення). Таким чином, ви зазвичай робите зліва людей від замовлень. Але тоді вам доведеться приєднатися до спеціальних деталей порядку. Якщо ви використовуєте внутрішнє з'єднання там, це ефективно зробить ліве з'єднання від людей до замовлень на внутрішнє з'єднання. IE: це те, що ви хочете зробити, але не працює (це виключає тих, хто не має спеціального замовлення):

select p.*, o.*, d.*
from Persons p
left join Orders o on o.CustomerId = p.Id
inner join SpecialOrderDetails d on d.OrderId = o.Id

Отже, ви можете переписати це так:

--get all the people without a special order
select p.*, NULL, NULL, ... --NULLs placeholders for all the fields from OrderDetails and SpecialOrderDetails
from Persons p
left join Orders o on o.CustomerId = p.Id
left join SpecialOrderDetails d on d.OrderId = o.Id
where o.Id is null 

union

--get all the people with a special order
select p.*, o.*, d.*
from Persons p
inner join Orders o on o.CustomerId = p.Id
inner join SpecialOrderDetails d on d.OrderId = o.Id

Не зовсім зрозуміло (не маючи коментарів), але це робить свою роботу. Якщо це щось більше, ніж разове (тобто те, що комусь доведеться повернутися і зберегти колись), використовуючи право приєднання, це може зрозуміти, у чому намірилися.

select p.*, o.*, d.*
from Orders o
inner join SpecialOrderDetails d on d.OrderId = o.Id
right join Persons p on p.Id = o.CustomerId

Що трохи більш лаконічно і зрозуміло (але лише якщо той, хто його читає, той розуміє, як правильно). Зауважте, що це може бути записано з лівими приєднаннями, але це потребує вкладеного з'єднання (яке, мабуть, менше людей знайоме, ніж право приєднується).

select p.*, o.*, d.*
from Persons p
left join Orders o 
    inner join SpecialOrderDetails d on d.OrderId = o.Id
on o.CustomerId = p.Id

На даний момент, це вибір того, що є найбільш зрозумілим і що зрозуміють більшість людей (чи знаєте ви, як гуглювати цей синтаксис, якби ви не знали, що це називається вкладеним об'єднанням?).

Коротше кажучи, вам не потрібно строго приєднуватись, але вони можуть полегшити читання.


Я думаю, може, ти просто правша.
Роберт Харві

Я не розумію , чому ви не можете писати множинним лівої приєднується в даному випадку: SELECT p.*, o.*, d.* FROM Persons p LEFT JOIN Orders o ON o.CustomerID = p.ID LEFT JOIN SpecialOrders d ON o.Id = d.OrderID.
Зев Шпіц

@RobertHarvey Я, але я не впевнений, що стосується цього.
Becuzz

@ ZevSpitz Можливо, з того, що я написав, було не зрозуміло, але ідея полягала в тому, що ви хотіли, щоб поля з замовлень були лише в тому випадку, якщо існує специфічний запис деталей замовлення, тобто. зліва приєднуйтесь до них лише за наявності їх пари.
Becuzz

-1

Я бачив, як ПРАВИЛЬНЕ ПРИЄДНАННЯ використовується для реплікації / злиття. Скажімо, у мене дві таблиці A і B. A - зліва, а B - справа. Скажімо, я хотів копіювати дані між цими двома таблицями, щоб зробити їх рівнозначними.

Якби я хотів показати всі дані, які були в A, але не в B, це було б лівим приєднанням. Якби я хотів показати всі дані в B, яких не було в A, це ПРАВО приєднається.

Так, іноді ліворуч і праворуч стають у пригоді під час об’єднання та копіювання даних, щоб забезпечити перспективність.

Крім цього, я не бачу ніякої іншої причини використовувати ПРАВИЛЬНЕ приєднання, оскільки всі об'єднання RIGHT можуть бути перетворені на ліві приєднання або навпаки, усі ліві об'єднання можуть бути перетворені на ПРАВНІ приєднання, залежно від того, як впорядковані та візуалізовані таблиці. Отже, це було б питанням уподобань в інших випадках.

Ось приємне посилання для візуалізації SQL Joins.

http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins


-1

ліве об'єднання не є протилежністю правого об'єднання, перевірте наступний випадок, який дає різні результати

select * from 
(select 1 as x  where 1=1) a left join 
(select 1 as x  where 1=0) b on a.x=b.x inner join 
(select 1 as x  where 1=1) c on b.x=c.x

select * from 
(select 1 as x where 1=1) c inner join 
(select 1 as x where 1=0) b on c.x=b.x right join 
(select 1 as x where 1=1) a on b.x=a.x

таблиці b anc c завжди з'єднані внутрішньо, але в першому a з’єднано ліворуч з іншими, а на другому a - праворуч з'єднано

ліве з'єднання не повертає рядків, а праве приєднання повертає рядок


це більше схоже на дотичний коментар, див. Як відповісти
gnat

-2

Ніколи немає жодної причини віддавати перевагу RIGHT JOIN, і LEFT JOINце набагато зрозуміліше:

SELECT Persons. *, Orders. * OF Persons ЛІВО ПРИЄДНАЙТЕ замовлення ON Persons.ID = Orders.PersonID

оскільки це дозволяє відразу побачити, яку таблицю запитують. Тоді як RIGHT JOIN:

ВИБРАТИ Особи. *, Замовлення. * З замовлень ПРАВО ПРИЄДНАЙТЕСЬ Особи НА Замовлення.PersonID = Persons.ID

Перша таблиця пишеться після JOIN.

З мого досвіду, я ніколи не бачив RIGHT JOIN.


1
Що це додає до питання? Питання не в чому різниця? ; Питання полягає в тому, чому я повинен використовувати RIGHT JOIN? .
Зев Шпіц

@ZevSpitz Ви запитуєте причину, щоб віддати перевагу якій із них, я даю вам причину. Який варіант використання не має значення, оскільки це питання смаку.
kirie
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.