Oracle SQL三查询验证及第三查询求解:订单、客户表操作
SQL查询分析与修正
先明确三张表结构:
- orders表:
ORDERID, CUSTOMERID, EMPLOYEEID, TERRITORYID, ORDERDATE, REQUIREDDATE, SHIPPEDDATE, SHIPVIA, FREIGHT, SHIPNAME, SHIPADDRESS, SHIPCITY, SHIPREGION, SHIPPOSTALCODE, SHIPCOUNTRY - orderdetails表:
ORDERID, PRODUCTID, UNITPRICE, QUANTITY, DISCOUNT - customers表:
CUSTOMERID, COMPANYNAME, CONTACTNAME, CONTACTTITLE, ADDRESS, CITY, REGION, POSTALCODE, COUNTRY, PHONE, FAX
1. 总金额超过10000的订单查询
原语句正确性
你的原语句是正确的,它通过关联orders和orderdetails表,按orderid分组后筛选出总金额(unitprice * quantity * (1 - discount))超过10000的订单ID。
优化写法
如果orderdetails表中的orderid均对应orders表的有效订单,无需关联orders表,直接查询orderdetails即可减少关联开销:
SELECT orderid FROM orderdetails GROUP BY orderid HAVING SUM(unitprice * quantity * (1 - discount)) > 10000;
若需确保订单存在(比如orderdetails可能包含无效orderid),保留原关联写法即可。
2. 总金额最高的订单查询
原语句问题
你的原语句不正确:未按orderid分组时,SUM(unitprice * quantity * (1 - discount))会计算所有订单的总金额,MAX(orderid)仅返回所有订单中最大的ID,两者没有对应关系,无法得到正确结果。
正确写法
方法1:排序取单条(仅返回一个最高金额订单)
适合仅需获取任意一个最高金额订单的场景:
SELECT orderid, SUM(unitprice * quantity * (1 - discount)) AS total_amount FROM orders JOIN orderdetails USING(orderid) GROUP BY orderid ORDER BY total_amount DESC LIMIT 1;
方法2:窗口函数(返回所有并列最高金额的订单)
支持窗口函数的数据库(如MySQL 8+、PostgreSQL、SQL Server等)可用此方法,能返回所有金额并列最高的订单:
SELECT orderid, total_amount FROM ( SELECT orderid, SUM(unitprice * quantity * (1 - discount)) AS total_amount, RANK() OVER(ORDER BY SUM(unitprice * quantity * (1 - discount)) DESC) AS rank_num FROM orders JOIN orderdetails USING(orderid) GROUP BY orderid ) AS order_amounts WHERE rank_num = 1;
3. 订单运费总和超过2000的客户查询
原语句问题
你的原语句存在两处错误:
HAVING Count(freight) > 2000统计的是客户的订单数量,而非运费总和;SELECT freight在分组后无法直接返回单个订单的运费,需返回运费总和。
正确写法
基础版(仅返回客户ID和总运费)
无需关联customers表,直接从orders表分组计算即可:
SELECT customerid, SUM(freight) AS total_freight FROM orders GROUP BY customerid HAVING SUM(freight) > 2000;
扩展版(包含客户其他信息)
若需显示客户的公司名等信息,关联customers表:
SELECT c.customerid, c.companyname, SUM(o.freight) AS total_freight FROM customers c JOIN orders o USING(customerid) GROUP BY c.customerid, c.companyname HAVING SUM(o.freight) > 2000;
内容的提问来源于stack exchange,提问作者Rayman
相关产品推荐
相关产品推荐

