почему требуется правое соединение или сделано, в котором мы можем получить данные только с помощью левого соединения с перетасовкой порядка таблицы [duplicate]

Вы также получите эту ошибку, если забудете new:

String s = String();

в сравнении с

String s = new String();
41
задан Roman Pekar 20 February 2015 в 15:27
поделиться

11 ответов

Единственная причина, по которой я могу думать о том, чтобы использовать RIGHT OUTER JOIN, - это попытаться сделать ваш SQL более самодокументированным.

Возможно, вы захотите использовать левые соединения для запросов с нулевыми строками в зависимая (много) сторона отношений «один ко многим» и правильное объединение по тем запросам, которые генерируют нулевые строки в независимой стороне.

Это также может происходить в сгенерированном коде или если требования к кодированию магазина определяют порядок объявления таблиц в предложении FROM.

29
ответ дан Yes - that Jake. 20 August 2018 в 17:37
поделиться
  • 1
    +1, согласился бы ответить, если бы он подвел итоги, Майкл и Иван. – DCookie 15 January 2009 в 19:57
  • 2
    мы можем получить те же результаты, используя левое внешнее соединение (кстати, мы используем правое внешнее соединение). Тогда почему есть опция для правого соединения или наоборот ?. – Hell Boy 22 February 2016 в 08:32
SELECT * FROM table1 [BLANK] OUTER JOIN table2 ON table1.col = table2.col

Замените [BLANK] на:

LEFT - если вы хотите, чтобы все записи из таблицы1 даже если у них нет col, который соответствует таблице2 (также включены записи таблицы2 со спичками)

RIGHT - если вы хотите, чтобы все записи из таблицы2, даже если у них нет col, который соответствует таблице1 (также включены записи таблицы 1 со спичками)

FULL - если вы хотите, чтобы все записи из таблицы1 и из таблицы2

О чем все говорят? Они такие же? Я так не думаю.

3
ответ дан Andrew G. Johnson 20 August 2018 в 17:37
поделиться
  • 1
    Вы всегда можете заменить RIGHT OUTER JOIN LEFT OUTER JOIN, который производит тот же ответ, и наоборот. – DCookie 12 January 2009 в 19:50
  • 2
    Вы имеете в виду, что вы просто замените слова «LEFT»? и "ПРАВО" или вы имеете в виду, что вы набрасываетесь на синтаксис запроса? – Andrew G. Johnson 12 January 2009 в 20:54
  • 3
    вы также должны изменить порядок таблиц в соединении. – HLGEM 12 January 2009 в 22:18
  • 4
    @ Андрей: последний. Всегда можно выразить данную ПРАВИЛЬНУЮ ВНУТРЕННУЮ СОЕДИНЕНИЕ с эквивалентной ВЛЕВОЙ ВЗАИМОДЕЙШЕЙ РАБОТОЙ, например, выбрать ... из правого внешнего соединения b, используя (x); может быть выражен как select ... from b left external join a using (x); Отсюда вопрос, зачем использовать ПРАВИЛЬНЫЙ ВЗГЛЯД? – DCookie 12 January 2009 в 22:29
  • 5
    Я согласен, что RIGHT OUTER JOINs очень редко используются, но говорят, что они одинаковые, очень вводят в заблуждение кого-то, кто не знаком с SQL и JOIN. Я думаю, что единственный раз, когда я использовал ROJ, это запрос MS Access & quot; -- какой кошмар :/ – Andrew G. Johnson 13 January 2009 в 10:59

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

Этот пример из Wikipedia показывает, что я имею в виду:

SELECT *  
FROM   employee 
   FULL OUTER JOIN department 
      ON employee.DepartmentID = department.DepartmentID

Если вы просто замените слово FULL на RIGHT, у вас есть новый запрос, не заменяя порядок предложения ON.

5
ответ дан Bill the Lizard 20 August 2018 в 17:37
поделиться
  • 1
    Как это получило ПОЛНОЕ заявление? Плохо написанный запутанный запрос? – dkretz 13 January 2009 в 00:39
  • 2
    FULL имеет свою цель и не всегда нуждается в «фиксации» и заменяет его на RIGHT, не делает то же самое. Что делать, если вы создаете отчет, чтобы помочь компании утвердить назначения сотрудников и отделов, и хотите включить отделы, у которых нет сотрудников, а также сотрудников, которые не были назначены отделу? – utexaspunk 12 February 2014 в 17:51

Операторы SQL, в дополнение к правильности, должны быть максимально просты в чтении и выразительном сжатии (поскольку они представляют собой одиночные атомарные действия, и ваш ум должен полностью их убеждать, чтобы избежать непредвиденных последствий.) Иногда выражение больше четко обозначается правым внешним соединением.

Но всегда можно преобразовать в другое, и оптимизатор будет делать то же самое с другим, как и другим.

. Некоторое время, по крайней мере, один из основных продуктов rdbms поддерживает только LEFT OUTER JOIN. (Я считаю, что это был MySQL.)

2
ответ дан dkretz 20 August 2018 в 17:37
поделиться
  • 1
    «Иногда выражение более четко выражено с помощью правого внешнего соединения». Я боюсь, когда это может произойти. Зачем использовать синтаксис, который в основном является обратным к другому, более часто используемому? У вас есть пример? – DCookie 12 January 2009 в 23:59
  • 2
    Неа. Я никогда не использовал RIGHT OUTER JOIN сам: D. – dkretz 13 January 2009 в 00:37

Единственные времена, когда я использовал правильное соединение, были, когда я хочу посмотреть два набора данных, и у меня уже есть соединения в определенном порядке для левого или внутреннего соединения из ранее написанного запроса. В этом случае, скажем, вы хотите видеть в качестве одного набора данных записи, не включенные в таблицу a, а в таблицу b, а в другом - записи не в таблице b, а в таблице a. Даже тогда я, как правило, делаю это, чтобы сэкономить время на исследование, но изменил бы его, если бы это был код, который будет запускаться более одного раза.

2
ответ дан HLGEM 20 August 2018 в 17:37
поделиться

Я думаю, что это сложно, если вы не имеете права присоединиться к этому делу. ex с оракулом.

with a as(
     select 1 id, 'a' name from dual union all
     select 2 id, 'b' name from dual union all
     select 3 id, 'c' name from dual union all
     select 4 id, 'd' name from dual union all
     select 5 id, 'e' name from dual union all
     select 6 id, 'f' name from dual 
), bx as(
   select 1 id, 'fa' f from dual union all
   select 3 id, 'fb' f from dual union all
   select 6 id, 'f' f from dual union all
   select 6 id, 'fc' f from dual 
)
select a.*, b.f, x.f
from a left join bx b on a.id = b.id
right join bx x on a.id = x.id
order by a.id
0
ответ дан Hong Van Vit 20 August 2018 в 17:37
поделиться
  • 1
    select a.*, b.f, x.f from bx x left outer join a on a.id = x.id left join bx b on b.id = a.id order by a.id – JohnLBevan 30 November 2017 в 18:06

В некоторых базах данных SQL есть подсказки оптимизатора, которые сообщают оптимизатору о соединении таблиц в том порядке, в котором они появляются в предложении FROM - например, /*+ORDERED */ в Oracle. В некоторых простых реализациях это может быть даже единственным доступным планом выполнения.

В таких случаях порядок таблиц в предложении FROM имеет значение, так что RIGHT JOIN может быть полезным.

1
ответ дан Jiri Tousek 20 August 2018 в 17:37
поделиться
SELECT * FROM table_a
INNER JOIN table_b ON ....
RIGHT JOIN table_c ON ....

Как еще вы могли бы быстро / легко встроить первые 2 таблицы и присоединиться к table_c, гарантируя, что все строки в таблице_c всегда выбраны?

2
ответ дан Matt 20 August 2018 в 17:37
поделиться
  • 1
    Вы можете сначала перечислить table_c, а слева - присоединиться к другим. – DCookie 7 October 2012 в 19:39
  • 2
    Записывая это, синтаксис @ Matt выглядит более читаемым, чем эквивалент: SELECT * FROM table_c LEFT JOIN ( SELECT * FROM table_a INNER JOIN table_b ON .... ) ON .... – 8forty 1 January 2018 в 21:15

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

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

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

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

1
ответ дан mattpm 20 August 2018 в 17:37
поделиться
  • 1
    тогда не читал комментарий выше? Разве это не странно, как думают программисты, потому что они не использовали что-то, что оно каким-то образом избыточно, когда на самом деле, возможно, они должны обновить свой набор навыков, чтобы понять краевые случаи. – Dawesi 11 April 2018 в 04:51

B ПРАВОЕ СОЕДИНЕНИЕ A такое же, как A LEFT JOIN B

B ПРАВОЕ СОЕДИНЕНИЕ A гласит: B ON RIGHT, THEN JOINS A. означает, что A находится в левой части набора данных. точно так же, как A LEFT JOIN B

Нет производительности, которую можно получить, если вы измените LEFT JOINs на RIGHT.

Единственные причины, по которым я могу подумать, почему use RIGHT JOIN - это если вы тип человека, который любит думать изнутри (выберите * from detail right join header).

Другим является то, что у вас уже есть обширный запрос, в котором вы хотите добавить еще один стол, когда это боль в шее, чтобы переупорядочить запрос, поэтому просто подключите таблицу к существующему запросу, используя ПРАВИЛЬНЫЙ JOIN.

9
ответ дан Michael Buen 20 August 2018 в 17:37
поделиться
  • 1
    +1, согласился бы ответить, если бы он подвел итоги, Декке и Ивана. – DCookie 15 January 2009 в 19:56
  • 2
    нет производительности ... нет большой причины научиться использовать язык, как он был предназначен. Если все было сделано по соображениям производительности, Ruby и php и .net больше не будут. – Dawesi 11 April 2018 в 04:56

Раньше я никогда не использовал right join и никогда не думал, что на самом деле мне это может понадобиться, и кажется немного неестественным. Но после того, как я подумал об этом, это может быть действительно полезно в ситуации, когда вам нужно внешнее соединение одной таблицы с пересечением многих таблиц, поэтому у вас есть такие таблицы:

enter image description here [/g0]

И хочу получить такой результат:

enter image description here [/g1]

Или, в SQL (MS SQL Server):

declare @temp_a table (id int)
declare @temp_b table (id int)
declare @temp_c table (id int)
declare @temp_d table (id int)

insert into @temp_a
select 1 union all
select 2 union all
select 3 union all
select 4

insert into @temp_b
select 2 union all
select 3 union all
select 5

insert into @temp_c
select 1 union all
select 2 union all
select 4

insert into @temp_d
select id from @temp_a
union
select id from @temp_b
union
select id from @temp_c

select *
from @temp_a as a
    inner join @temp_b as b on b.id = a.id
    inner join @temp_c as c on c.id = a.id
    right outer join @temp_d as d on d.id = a.id

id          id          id          id
----------- ----------- ----------- -----------
NULL        NULL        NULL        1
2           2           2           2
NULL        NULL        NULL        3
NULL        NULL        NULL        4
NULL        NULL        NULL        5

Итак, если вы переключитесь на left join, результаты не будут одинаковыми.

select *
from @temp_d as d
    left outer join @temp_a as a on a.id = d.id
    left outer join @temp_b as b on b.id = d.id
    left outer join @temp_c as c on c.id = d.id

id          id          id          id
----------- ----------- ----------- -----------
1           1           NULL        1
2           2           2           2
3           3           3           NULL
4           4           NULL        4
5           NULL        5           NULL

Единственный способ сделать это без правильного соединения - использовать общее выражение таблицы или подзапрос

select *
from @temp_d as d
    left outer join (
        select *
        from @temp_a as a
            inner join @temp_b as b on b.id = a.id
            inner join @temp_c as c on c.id = a.id
    ) as q on ...
15
ответ дан Roman Pekar 20 August 2018 в 17:37
поделиться
  • 1
    Вам не нужно вставлять SELECT, вместо этого вы можете вложить соединение: FROM @temp_d AS d LEFT OUTER JOIN (temp_a AS a INNER JOIN @temp_b AS b ON b.id = a.id INNER JOIN @temp_c AS c ON c.id = a.id) ON a.id = d.id. (Скобки не нужны, они добавляются только для удобства чтения). Правда, есть люди, которые не определились в отношении того, какой синтаксис они предпочитают больше, вложенные объединения или внешние внешние соединения, поэтому возможно, что правильные объединения могут работать < i> менее плохо для них. :) – Andriy M 16 March 2016 в 13:35
  • 2
    Приятно, я никогда не использовал синтаксис вложенных объединений :) – Roman Pekar 10 December 2016 в 15:22
Другие вопросы по тегам:

Похожие вопросы: