Подзапрос и обычный запрос дают разные результаты - PullRequest
1 голос
/ 06 ноября 2019

Я новичок оракула, в настоящее время я делаю вопрос, используя подзапрос (без JOIN) и обычный (с JOIN) запрос, но в конце результаты отличаются от этих двух запросов, я могуКто-нибудь знает эту проблему?

Вопрос состоит в том, чтобы узнать список владельцев собак, которые хотя бы дважды забронировали на этой платформе

SELECT PET_OWNER.Owner_id,Oname,OAdd,COUNT(*) AS BOOKING 
FROM PET_OWNER 
WHERE Owner_id IN(
  SELECT Owner_id 
  FROM PET 
  WHERE PType = 'DOG' AND Pet_id IN(SELECT Pet_id FROM BOOKING))
GROUP BY PET_OWNER.Owner_id,Oname,OAdd
HAVING COUNT(*) >=2
ORDER BY PET_OWNER.Owner_id;

В этом подзапросе нет строквыбран,

SELECT PET_OWNER.Owner_id,Oname,OAdd,COUNT(*) AS BOOKING 
FROM PET_OWNER,PET,BOOKING 
WHERE PET_OWNER.Owner_id = PET.Owner_id AND 
  PET.Pet_id = BOOKING.Pet_id AND 
  PType = 'DOG'
GROUP BY PET_OWNER.Owner_id,Oname,OAdd
HAVING COUNT(*) >=2
ORDER BY PET_OWNER.Owner_id;

этот запрос показывает 10 записей, которые являются правильным ответом на этот вопрос

Я ожидал, что эти два запроса получат одинаковый результат, но никто не знает, что эточто-то не так?

Может кто-нибудь показать мне, как преобразовать этот код в подзапрос?

Ответы [ 2 ]

0 голосов
/ 06 ноября 2019

Поскольку дублированный ключ соединения приведет к дублированию в результате. В вашем случае Owner_id должен быть неуникальным в таблице PET. Все еще возможно получить правильный ответ, используя соединение. А поскольку owner_id в подзапросе t уникален, план выполнения должен быть таким же, как и в версии подзапроса.

select p.* from Pet_Owner p
join (
    select PET.Owner_id 
    from PET
    inner join Booking on Booking.Pet_id = PET.Pet_id
    where pType = 'DOG'
    group by PET.Owner_id
    having count(1) >= 2) t
on t.Owner_id = p.Owner_id 
order by p.Owner_id

Кстати, ваш код SQL настолько стар, как в ANSI-89, а синтаксис объединения уже в ANSI-92. Я знаю, что многие школьные учителя все еще любят старый стиль, я надеюсь, что вы можете читать и то, и другое, но писать код только в формате ANSI-92.

0 голосов
/ 06 ноября 2019

Что произойдет, так это то, что он даст вам различные значения на вашем PET_OWNER.Owner_id,Oname,OAdd. Так что нам нужно сначала group by owner_id.

Вот ваш запрос. получите первые те owner_id с count() >= 2 как subquery

select * from Pet_Owner where Owner_id in (
    select t1.Owner_id from PET_OWNER t1
    inner join PET t2 on t1.Owner_id = t2.Owner_id
    inner join Booking t3 on t3.Pet_id = t2.Pet_id
    where pType = 'DOG'
    group by t1.Owner_id
    having count(1) >= 2)
order by Owner_id

без использования объединения , nested subqueries - наш единственный вариант

select * from Pet_Owner where Owner_id in (
    select owner_id from Pet_Owner where Owner_id in 
        (select Owner_id from Pet where Pet_id in 
            (select Pet_id in Booking) and PType='DOG')
    group by owner_id
    having count(1) >= 2)
order by Owner_id

, еслиВы пытаетесь # of dogs на владельца:

select * from Pet_Owner where Owner_id in (
    select Owner_id from Pet where Pet_id in 
        (select Pet_id in Booking) and PType='DOG'
    group by owner_id
    having count(1) >= 2)
) order by Owner_id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...