Почему эти 2 «эквивалентных» запроса возвращают разное количество строк?

#sql

#sql

Вопрос:

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

 select ip.* 
from invoice_payment ip
inner join invoice_item II on ii.invoice_item_uuid = ip.invoice_item_uuid
inner join service_delivery sd on sd.service_delivery_uuid = ii.service_delivery_uuid
inner join #Affected on #Affected.service_delivery_uuid = sd.service_delivery_uuid


select * 
from invoice_payment ip
where ip.invoice_item_uuid in (
  select ii.invoice_item_uuid from invoice_item ii
  where ii.service_delivery_uuid in (
    select service_delivery_uuid from #Affected)
)
  

Спасибо!

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

1. Они не являются эквивалентными запросами

Ответ №1:

Первый возвращает продукт:

 IP x II x sd x #Affected
  

Затем продукт ограничен on условиями. Но если какое-либо условие соответствует нескольким строкам, в конечном итоге у вас будет больше строк, чем в IP таблице.

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

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

1. Спасибо, Андомар. Итак, вы говорите, что 2-й более точный? Я превращу этот выбор в удаление, поэтому важно, чтобы я получил правильный результат.

2. Да, второй будет более точно фиксировать удаление.

Ответ №2:

Если какая-либо из таблиц invoice_item, service_delivery или #Affected содержит более одной записи, соответствующей таблице, к которой она присоединена, то это увеличит количество записей в результирующем наборе, фактически умножая количество сообщений о invoice_payment.

Поскольку мне кажется вероятным, что invoice_payment может соответствовать более чем одному invoice_item, вот где я бы посмотрел в первую очередь.

Два запроса, кстати, даже приблизительно не эквивалентны.