Oracle SQL使用子查询

时间:2016-02-22 20:22:26

标签: oracle subquery correlated-subquery

我在学习子查询时遇到了一些麻烦。我试图展示每个客户订购过的最昂贵的图书,并使用不相关的子查询进行编写。

这是我到目前为止所做的:

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,我们将非常感谢任何帮助

3 个答案:

答案 0 :(得分:0)

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;

答案 1 :(得分:0)

这里的缺陷是你的逻辑,而不是语法。内部查询返回每个客户的最大零售价,然后外部查询返回与这些价格之一匹配的任何连接行。考虑一下你有两个顾客的情况 - 顾客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

答案 2 :(得分:0)

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;