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

Вот что у меня есть на данный момент:

select Firstname || ', '|| Lastname "Name", title, retail
from Customers join orders using (Customer#) join orderitems using (Order#)                 
join books using (Isbn)
where retail =ANY (select max(retail)
                from books join orderitems using (isbn) join Orders using (order#) join Customers using (Customer#)
                group by Customer#)                 
order by  Firstname, Lastname;

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

1
Big T 22 Фев 2016 в 23:22

3 ответа

Лучший ответ
select Firstname || ', '|| Lastname "Name", title, retail
from Customers join orders using (Customer#) join orderitems using (Order#)                 
join books using (Isbn)
where (Customer#, retail) in (select Customer#,  max(retail)
                from books join orderitems using (isbn) join Orders using (order#) join Customers using (Customer#)
                group by Customer#)                 
order by  Firstname, Lastname;

Или как мне нравится делать это, не выбирая одно и то же дважды:

select Name, title, Customer#, retail
from (select Firstname || ', '|| Lastname "Name", title, Customer#,  
             retail, max(retail) over (partition by  Customer#) max_retail
        from books 
        join orderitems using (isbn) 
        join Orders using (order#) 
        join Customers using (Customer#))    
where retail=max_retail             
order by  Firstname, Lastname;
0
a.j. tawleed 22 Фев 2016 в 21:00

Ошибка здесь в вашей логике, а не в синтаксисе. Внутренний запрос возвращает максимальную розничную цену для каждого покупателя, а затем внешний запрос возвращает любую присоединенную строку, которая соответствует одной из этих цен. Рассмотрим случай, когда у вас есть два клиента: клиент 1 совершил покупки, один за 10 долларов и один за 20 долларов, а клиент 2 сделал только одну покупку на 10 долларов. Внутренний запрос вернет 20 долларов (максимальная покупка покупателя 1) и 10 долларов (максимальная покупка покупателя 2), а затем внешний запрос вернет все покупки в любой из этих сумм, т.е. все три ряда. "Учебным" решением было бы rank покупок каждого покупателя и возвращать только самую лучшую покупку на покупателя:

SELECT   name, title, retail
FROM     (SELECT firstname || ', '|| lastname AS name,
                 title, 
                 retail,
                 RANK() OVER (PARTITION BY customer# ORDER BY retail DESC) AS rk
          FROM   customers
          JOIN   orders USING (customer#)
          JOIN   orderitems USING (order#)                 
          JOIN   books USING (isbn))
WHERE    rk = 1
ORDER BY 1
0
Mureinik 22 Фев 2016 в 20:42
select 
  Firstname || ', '|| Lastname "Name"
  ,max(retail) "Most expensive book by customer"
from 
  Customers c, Orders o, OrderItems oi, Books b 
where c.customer#=o.customer# 
  and o.order#=oi.order# 
  and oi.isbn=b.isbn
group by Firstname || ', '|| Lastname;
0
access_granted 22 Фев 2016 в 20:56