Эквивалентно ли соединение запросу с подзапросом для столбца?

#sql

#sql

Вопрос:

Извините за вопросы новичка в sql, но разве это не одно и то же:

 select a.productid, sum(b.qty)
from table1 a
inner join table2 b on b.productid = a.productid
group by a.productid
;

select a.productid
,(select sum(b.qty) from table2 b where b.productid = a.productid)
from table1 a
group by a.productid
;
  

Зачем кому-либо вообще использовать запрос, подобный приведенному выше, в select, это какая-то старая школьная штука, о которой нужно забыть, или мне все еще следует рассмотреть возможность ее использования для некоторых возможных будущих проблем?

Комментарии:

1. Могу ли я предложить другое название для вашего вопроса, пожалуйста? Что-то вроде «Эквивалентно ли соединение запросу с подзапросом для столбца?», например

2. да, имеет смысл, могу ли я изменить заголовок сейчас после публикации?

3. Вероятно, вы не можете редактировать (хотя и не уверены), потому что вы новичок. При достаточной репутации / баллах вы сможете. Я сделаю это. Я понимаю, что вас это устраивает.

Ответ №1:

Нет, на самом деле это не одно и то же. Существует множество различий, но наиболее очевидным является то, что join будет отфильтровывать любые несоответствующие строки. Коррелированный подзапрос вернет все строки в первой таблице.

Есть и другие различия. sum() s не будут одинаковыми, если в первой таблице есть дубликаты productid s. Планы выполнения будут другими (потому что наборы результатов разные). При некоторых обстоятельствах соответствующий подзапрос будет выполняться быстрее.

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

Ответ №2:

Первый запрос:

 select a.productid, sum(b.qty)
from table1 a
inner join table2 b on b.productid = a.productid
group by a.productid
  

Оно не вернет строку, если в table2 нет соответствующего значения.

Второй запрос имеет вид LEFT JOIN :

 select a.productid
,(select sum(b.qty) from table2 b where b.productid = a.productid)
from table1 a
group by a.productid
<=>
select a.productid, sum(b.qty)
from table1 a
left join table2 b on b.productid = a.productid
group by a.productid
  

Ответ №3:

Помните о производительности … внутреннее соединение выполняется намного быстрее, чем подзапрос. Подвыборка перебирает все совпадающие результаты, поэтому сложность составляет N x M … что приводит к снижению производительности. В большинстве случаев соединения имеют лучшую производительность.

Смотрите https://www.essentialsql.com/subquery-versus-inner-join /

Комментарии:

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

2. @Gordon, я согласен с вами, что подзапросы могли бы быть быстрее (например, когда оптимизатор БД может улучшить план выполнения). Вот почему я писал в большинстве случаев . Если вы считаете, что мой ответ в целом некорректен, пожалуйста, предоставьте какие-либо доказательства.

3. . . . «внутреннее соединение выполняется намного быстрее, чем подзапрос». False.