题解 | 返回每个顾客不同订单的总金额
返回每个顾客不同订单的总金额
https://www.nowcoder.com/practice/ce313253a81c4947b20e801cd4da7894
思路分析:
题目需要返回每个顾客的cust_id以及他们订购的订单总金额,可以看到每一个顾客都对应一个order_num,在OrderItems表中有订单信息,将相同order_num的记录聚合到一起,将这些记录对应的item_price * price加总,就是这个order_num的总的订单金额,也就是这个order_num所对应的cust_id的订单金额。可以看到数据涉及两个表之间的联动,两种方式,一种使用表连接,另外一种使用关联标量子查询。
代码解释:
方法一:表连接
SELECT cust_id, total_ordered FROM Orders JOIN ( SELECT order_num, SUM(item_price * quantity) AS total_ordered FROM OrderItems GROUP BY order_num ) AS total ON Orders.order_num = total.order_num ORDER BY total_ordered DESC;
将Orders表和一张临时表连接,在临时表中进行分组聚合,计算每个order_num的总金额,通过order_num相等使两表连接,最后选择cust_id和total_ordered即可。
方法二:关联标量子查询
SELECT cust_id, ( SELECT SUM(item_price * quantity) FROM OrderItems WHERE OrderItems.order_num = Orders.order_num ) AS total_ordered FROM Orders ORDER BY total_ordered DESC;
不需要连接,仅从Orders表中查询,在SELECT子句中直接嵌入子查询,形成一个新列,该子查询依赖于主查询提供的记录数据,针对主查询的每一条记录,返回单个值,因此属于关联标量子查询。整体的执行过程是:主查询依次遍历Orders表中的每一条记录,每遍历一条,就执行一次子查询,主查询首先抽取出第一条记录,获得一个Orders.order_num数据,子查询执行,进入OrderItems表中,查找表中OrderItems.order_num等于主查询中抽取出的这条Orders.order_num记录,针对这些记录求SUM(item_price * quantity),即求出该order_num的总金额,返回给主查询作为新列的第一行数据,接着主查询遍历Orders表中第二条记录,再次进入子查询执行,以此类推,当主查询遍历完所有记录,新列每一行的数据也就都有了,整个查询结束。可以看到使用这样的方式不需要GROUP BY分组,因为在子查询中的WHERE OrderItems.order_num = Orders.order_num是根据主查询的每一条记录到子查询的表中去筛选的,就相当于起到了分组的效果。最后子查询是直接作为新列的,因此赋予列名total_ordered。
两种方式的比较:
两种方法在结果上是相同的,但关联标量子查询采用的是循环嵌套的执行逻辑,当遇到表中数据量很大的情况时,关联标量子查询的效率可能不如表连接,实际场景中更推荐使用表连接的方式。