文章路径:数据库/基础/SQL/SQL常见面试题总结(1)/使用子查询/返回每个顾客不同订单的总金额
部分原文如下:
返回每个顾客不同订单的总金额
我们需要一个顾客 ID 列表,其中包含他们已订购的总金额。
OrderItems 表代表订单信息,OrderItems 表有订单号 order_num、商品售出价格 item_price、商品数量 quantity。
| order_num | item_price | quantity |
|---|
| a0001 | 10 | 105 |
| a0002 | 1 | 1100 |
| a0002 | 1 | 200 |
| a0013 | 2 | 1121 |
| a0003 | 5 | 10 |
| a0003 | 1 | 19 |
| a0003 | 7 | 5 |
Orders 表有订单号 order_num、顾客 id cust_id。
| order_num | cust_id |
|---|
| a0001 | cust10 |
| a0002 | cust1 |
| a0003 | cust1 |
| a0013 | cust2 |
【问题】
编写 SQL 语句,返回顾客 ID(Orders 表中的 cust_id),并使用子查询返回 total_ordered 以便返回每个顾客的订单总数,将结果按金额从大到小排序。
答案:
# 写法 1:子查询SELECTo.cust_idAS cust_id, tb.total_orderedAS total_ordered
FROM (SELECT order_num, Sum(item_price * quantity) AS total_ordered
FROM OrderItems
GROUP BY order_num) AS tb,
Orders o
WHEREtb.order_num=o.order_numORDER BY total_ordered DESC# 写法 2:连接表SELECTb.cust_id, Sum(a.quantity*a.item_price) AS total_ordered
FROM OrderItems a,Orders b
WHEREa.order_num=b.order_numGROUP BY cust_id
ORDER BY total_ordered DESC
这道题应该是想求每个顾客下的所有订单的总金额,并按照总金额从大到小进行排序。
文章中的“写法2:连接表”的 sql 是没有问题的,先以 order_num 为连接条件进行连表查询,然后按照 cust_id 进行分组,就可以计算每个顾客的所有订单的总和。
但是“写法 1:子查询”,先子查询得到每个订单的总金额,然后就只有根据 order_num 连表查询了,但是 cust_id 与 order_num 是一对多的关系,即一个顾客会有多个订单,因此在连表查询后还是需要对 cust_id 分组。
因此,写法1中还需要加上对 cust_id 的分组才是对的,即:
SELECTo.cust_id, SUM(tb.total_ordered) AS`total_ordered`FROM (SELECT order_num, SUM(item_price * quantity) AS total_ordered
FROM OrderItems
GROUP BY order_num) AS tb,
Orders o
WHEREtb.order_num=o.order_numGROUP BYo.cust_idORDER BY total_ordered DESC;
同时建议修改一下文中的“并使用子查询返回 total_ordered 以便返回每个顾客的订单总数”,这个订单总数有点歧义,建议修改成“并使用子查询返回每个订单的总金额 total_ordered”
测试:
CREATETABLE `OrderItems`(
`order_num`VARCHAR(16) NOT NULL COMMENT '订单号',
`item_price`INT UNSIGNED NOT NULL COMMENT '商品出售价格',
`quantity`INT UNSIGNED NOT NULL COMMENT '商品数量'
) COMMENT='订单商品信息表';
INSERT INTO`OrderItems`VALUES
('a0001', 10, 105),
('a0002', 1, 1100),
('a0002', 1, 200),
('a0013', 2, 1121),
('a0003', 5, 10),
('a0003', 1, 19),
('a0003', 7, 5);
CREATETABLE `Orders`(
`order_num`VARCHAR(16) NOT NULL COMMENT '订单号',
`cust_id`VARCHAR(16) NOT NULL COMMENT '顾客 id'
) COMMENT='订单表';
INSERT INTO`Orders`VALUES
('a0001', 'cust10'),
('a0002', 'cust1'),
('a0003', 'cust1'),
('a0013', 'cust2');文章中的写法1测试结果:
SELECTo.cust_idAS cust_id, tb.total_orderedAS total_ordered
FROM (SELECT order_num, Sum(item_price * quantity) AS total_ordered
FROM OrderItems
GROUP BY order_num) AS tb,
Orders o
WHEREtb.order_num=o.order_numORDER BY total_ordered DESC

修改后的写法1测试结果:
SELECTo.cust_id, SUM(tb.total_ordered) AS`total_ordered`FROM (SELECT order_num, SUM(item_price * quantity) AS total_ordered
FROM OrderItems
GROUP BY order_num) AS tb,
Orders o
WHEREtb.order_num=o.order_numGROUP BYo.cust_idORDER BY total_ordered DESC;

文章中的写法2测试结果:
SELECTb.cust_id, SUM(a.quantity*a.item_price) AS total_ordered
FROM OrderItems a,Orders b
WHEREa.order_num=b.order_numGROUP BY cust_id
ORDER BY total_ordered DESC;

文章路径:数据库/基础/SQL/SQL常见面试题总结(1)/使用子查询/返回每个顾客不同订单的总金额
部分原文如下:
返回每个顾客不同订单的总金额
我们需要一个顾客 ID 列表,其中包含他们已订购的总金额。
OrderItems表代表订单信息,OrderItems表有订单号order_num、商品售出价格item_price、商品数量quantity。Orders表有订单号order_num、顾客 idcust_id。【问题】
编写 SQL 语句,返回顾客 ID(
Orders表中的cust_id),并使用子查询返回total_ordered以便返回每个顾客的订单总数,将结果按金额从大到小排序。答案:
这道题应该是想求每个顾客下的所有订单的总金额,并按照总金额从大到小进行排序。
文章中的“写法2:连接表”的 sql 是没有问题的,先以 order_num 为连接条件进行连表查询,然后按照 cust_id 进行分组,就可以计算每个顾客的所有订单的总和。
但是“写法 1:子查询”,先子查询得到每个订单的总金额,然后就只有根据 order_num 连表查询了,但是 cust_id 与 order_num 是一对多的关系,即一个顾客会有多个订单,因此在连表查询后还是需要对 cust_id 分组。
因此,写法1中还需要加上对 cust_id 的分组才是对的,即:
同时建议修改一下文中的“并使用子查询返回
total_ordered以便返回每个顾客的订单总数”,这个订单总数有点歧义,建议修改成“并使用子查询返回每个订单的总金额total_ordered”测试:
文章中的写法1测试结果:
修改后的写法1测试结果:
文章中的写法2测试结果: