[英]How do I select the max value after a SUM() + Group By?
几天后我在大学里进行了一次SQL期末考试,我的查询让我发疯了! 我知道这是一个愚蠢的问题,但我刚刚开始,无法搞清楚。
所以,有基本的2个表,客户端和订单。
Client Orders
--------- ---------
PK Client_Id PK Order_Id
Name Client_Id FK
Order_Total
Date
现在,他们要我“列出2011年购买量最大的客户名称”
因此,对于我的想法,这需要一方面,我从2011年开始全部按Order_Total和Group by Client,然后从该表中选择具有MAX()总和的客户端,然后仅显示名称那个客户。 问题是我无法弄清楚如何将所有这些放在一个查询中。
希望有人可以帮忙!
谢谢大家的快速回复! 我真的很感动!
现在,我并不是说挑剔或任何东西,但为了防止我的老师不接受“限制”或“选择顶部”声明,有没有办法在没有这些的情况下进行此查询?
SELECT
C.NAME
FROM
CLIENTS C,
ORDERS O
WHERE
O.CLIENT_ID = C.CLIENT_ID
AND O.DATE BETWEEN '1/1/2011 00:00:00.000' and '12/31/2011 23:59:59.999'
HAVING SUM(O.ORDER_TOTAL) >= ALL (SELECT SUM (O2.ORDER_TOTAL) FROM ORDER O2 GROUP BY O2.CLIENT_ID)
SELECT T.X
(SELECT C.NAME X, SUM(O.ORDER_TOTAL)
FROM CLIENT C, ORDERS O
WHERE C.CLIENT_ID = O.CLIENT_ID
AND YEAR(O.DATE) = 2011
GROUP BY O.CLIENT_ID
ORDER BY 2 DESC
LIMIT 1) T;
有很多方法可以给这只猫上皮......这就是我通常会这样做的方法:
select top 1 c.Client_Id, c.Name, o.Order_Total
from Client c
join (select Client_Id, SUM(Order_Total) as Order_Total
from Orders
where `Date` between '1/1/2011 00:00:00.000' and '12/31/2011 23:59:59.999'
group by Client_Id) o
on c.Client_Id = o.Client_Id
order by o.Order_Total desc
基本上你是拉动订单总数列表,加入反对,按顺序排序降序,并将查询限制为1个结果。
根据你的问题,Is7aq的答案是正确的,但只适用于MySQL。 尽管我承认这不是原始问题中列出的约束,但它也没有考虑到一个以上客户在特定年份购买量最大的可能性。 一旦数据库变得足够大,通过简单地使用逗号来交叉连接也是一个巨大的性能损失,因此使用INNER或OUTER连接几乎总是更好,并指定连接的条件。 无论如何,这是一个练习,这就是我所拥有的。 它可能可以更好地优化:
CREATE TABLE #Client (
Client_Id int not null,
Name varchar(100) not null
)
INSERT INTO #Client VALUES (1, 'Client 1')
INSERT INTO #Client VALUES (2, 'Client 2')
INSERT INTO #Client VALUES (3, 'Client 3')
CREATE TABLE #Orders (
Order_Id int not null,
Client_Id int not null,
Order_Total int not null,
Date datetime not null
)
-- Customer 1: total=105
INSERT INTO #Orders VALUES (1, 1, 55, '1/1/2011')
INSERT INTO #Orders VALUES (2, 1, 50, '1/1/2011')
INSERT INTO #Orders VALUES (3, 1, 45, '1/1/2010') -- test removal of invalid dates
-- Customer 2: total=120
INSERT INTO #Orders VALUES (4, 2, 40, '1/1/2011')
INSERT INTO #Orders VALUES (5, 2, 40, '1/1/2011')
INSERT INTO #Orders VALUES (6, 2, 40, '1/1/2011')
-- Customer 3: total=120
INSERT INTO #Orders VALUES (7, 3, 40, '1/1/2011')
INSERT INTO #Orders VALUES (8, 3, 40, '1/1/2011')
INSERT INTO #Orders VALUES (9, 3, 40, '1/1/2011')
-- control customer to test hi/lo scenarios: total=40
INSERT INTO #Orders VALUES (10, 4, 10, '1/1/2011')
INSERT INTO #Orders VALUES (11, 4, 10, '1/1/2011')
INSERT INTO #Orders VALUES (12, 4, 10, '1/1/2011')
INSERT INTO #Orders VALUES (13, 4, 10, '1/1/2011')
SELECT T.NAME,
T.OrderTotal
FROM (SELECT C.NAME,
SUM(O.ORDER_TOTAL) OrderTotal
FROM #CLIENT C
INNER JOIN #ORDERS O
ON c.CLIENT_ID = o.CLIENT_ID
WHERE YEAR(O.DATE) = 2011
GROUP BY C.NAME) as T
WHERE T.OrderTotal = (SELECT MAX(T2.OrderTotal2)
FROM (SELECT C2.NAME,
SUM(O2.ORDER_TOTAL) OrderTotal2
FROM #CLIENT C2
INNER JOIN #ORDERS O2
ON c2.CLIENT_ID = o2.CLIENT_ID
WHERE YEAR(O2.DATE) = 2011
GROUP BY C2.NAME) as T2)
GROUP BY T.Name, T.OrderTotal
DROP TABLE #Client
DROP TABLE #Orders
-- Output
-- Client 2: 120
-- Client 3: 120
SELECT Client.Name
FROM Client LEFT JOIN Orders ON Orders.Client_Id = Client.Client_Id
WHERE YEAR(Orders.Date) = 2011
GROUP BY Client.Client_Id
ORDER BY SUM(Order.Order_Total) DESC
LIMIT 1
你几乎就在那里,你只需要从你的聚合查询中进行选择。 它被称为派生表。
所以你有这个:
select c.client_id, c.name, sum(order_total) ordersum
from client c
inner join orders o on c.client_id = o.client_id
where year(o.date) = 2011
group by c.client_id, c.name
这给了你你的金额。 现在你想要第一个。 有几种方法可以做到这一点,它还取决于你正在使用的DBMS(mysql,mssql等)。最简单的方法是:
select top 1 *
from (
select c.client_id, c.name, sum(order_total) ordersum
from client c
inner join orders o on c.client_id = o.client_id
where year(o.date) = 2011
group by c.client_id, c.name
) a
order by ordersum desc
在给定的平台上可能会有一些更简单的东西,但该查询应该足够通用,可以处理您正在使用的任何DBMS。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.