Sql server 获取订单最昂贵的客户的姓名
我有一个包含4个表的小数据库:Customer-Order-OrderLine-Product,我正在处理一些查询,并试图获取订单最昂贵的人的姓名 经过一番讨论后,我提出了以下查询,其中显示了所有订单的价格:Sql server 获取订单最昂贵的客户的姓名,sql-server,sql-server-2008-r2,Sql Server,Sql Server 2008 R2,我有一个包含4个表的小数据库:Customer-Order-OrderLine-Product,我正在处理一些查询,并试图获取订单最昂贵的人的姓名 经过一番讨论后,我提出了以下查询,其中显示了所有订单的价格: SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice, Orders.Id, Customer.Lastname FROM OrderLine, Product, Orders, Customer WHERE Orde
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice, Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
ORDER BY OrderLinePrice DESC
现在,从概念上讲,我需要做的,或者我认为我需要做的,是应用MAX()只选择最高的OrderLinePrice,但SQL Server抱怨无法对包含聚合的表达式执行聚合函数,这并不能让我成功
================更新:
当前我的查询如下所示:
SELECT t.CustomerLastName
FROM (
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice, Orders.Id, Customer.Lastname AS CustomerLastName
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
) AS t
WHERE t.OrderLinePrice =
(
SELECT MAX(s.OrderLinePrice) AS MaxOrderPrice
FROM (
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice, Orders.Id, Customer.Lastname AS CustomerLastName
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
) AS s
)
ORDER BY CustomerLastName
这将检索其订单价格等于最昂贵订单价格的客户列表。这正是我想要的,但感觉太多余了
我应该如何开始提高效率(如果可能的话)?您可以通过几种方法来实现这一点。以下是一些建议: CTE
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
MAX(OrderLinePrice) AS MaxorderPrice
FROM
CTE
具有最大值的子查询
SELECT
MAX(t.OrderLinePrice) AS MaxorderPrice
FROM
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
) AS t
排名靠前1的订单商
SELECT TOP 1
t.Amount
FROM
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
) AS t
ORDER BY t.OrderLinePrice DESC
编辑
也许是这样的:
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
*
FROM
CTE
WHERE
CTE.OrderLinePrice=(SELECT MAX(CTE2.OrderLinePrice) FROM CTE AS CTE2)
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
MAX(OrderLinePrice) AS MaxPrice,
Lastname
FROM
CTE
GROUP BY
CTE.Lastname
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT *
FROM (
SELECT TOP (1) WITH TIES CustomerLastName
FROM ranked
ORDER BY OrderLinePrice DESC
) s
ORDER BY CustomerLastName
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName,
RANK() OVER (ORDER BY SUM(ol.Amount * p.Price) DESC) AS rnk
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT CustomerLastName
FROM ranked
WHERE rnk = 1
ORDER BY CustomerLastName
或者,如果您希望按客户姓氏计算最大值。您可以这样做:
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
*
FROM
CTE
WHERE
CTE.OrderLinePrice=(SELECT MAX(CTE2.OrderLinePrice) FROM CTE AS CTE2)
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
MAX(OrderLinePrice) AS MaxPrice,
Lastname
FROM
CTE
GROUP BY
CTE.Lastname
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT *
FROM (
SELECT TOP (1) WITH TIES CustomerLastName
FROM ranked
ORDER BY OrderLinePrice DESC
) s
ORDER BY CustomerLastName
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName,
RANK() OVER (ORDER BY SUM(ol.Amount * p.Price) DESC) AS rnk
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT CustomerLastName
FROM ranked
WHERE rnk = 1
ORDER BY CustomerLastName
你可以通过两种方式来做到这一点。以下是一些建议: CTE
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
MAX(OrderLinePrice) AS MaxorderPrice
FROM
CTE
具有最大值的子查询
SELECT
MAX(t.OrderLinePrice) AS MaxorderPrice
FROM
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
) AS t
排名靠前1的订单商
SELECT TOP 1
t.Amount
FROM
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
) AS t
ORDER BY t.OrderLinePrice DESC
编辑
也许是这样的:
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
*
FROM
CTE
WHERE
CTE.OrderLinePrice=(SELECT MAX(CTE2.OrderLinePrice) FROM CTE AS CTE2)
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
MAX(OrderLinePrice) AS MaxPrice,
Lastname
FROM
CTE
GROUP BY
CTE.Lastname
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT *
FROM (
SELECT TOP (1) WITH TIES CustomerLastName
FROM ranked
ORDER BY OrderLinePrice DESC
) s
ORDER BY CustomerLastName
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName,
RANK() OVER (ORDER BY SUM(ol.Amount * p.Price) DESC) AS rnk
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT CustomerLastName
FROM ranked
WHERE rnk = 1
ORDER BY CustomerLastName
或者,如果您希望按客户姓氏计算最大值。您可以这样做:
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
*
FROM
CTE
WHERE
CTE.OrderLinePrice=(SELECT MAX(CTE2.OrderLinePrice) FROM CTE AS CTE2)
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
MAX(OrderLinePrice) AS MaxPrice,
Lastname
FROM
CTE
GROUP BY
CTE.Lastname
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT *
FROM (
SELECT TOP (1) WITH TIES CustomerLastName
FROM ranked
ORDER BY OrderLinePrice DESC
) s
ORDER BY CustomerLastName
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName,
RANK() OVER (ORDER BY SUM(ol.Amount * p.Price) DESC) AS rnk
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT CustomerLastName
FROM ranked
WHERE rnk = 1
ORDER BY CustomerLastName
首先,您是否考虑过使用显式联接?这可能只是口味的问题,但您可能会发现使用显式连接的查询比使用隐式连接(或“逗号”连接)的查询更清晰,如您的示例中所示 关于这个问题,你可以使用带领带的
TOP(1),如下所示:
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
*
FROM
CTE
WHERE
CTE.OrderLinePrice=(SELECT MAX(CTE2.OrderLinePrice) FROM CTE AS CTE2)
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
MAX(OrderLinePrice) AS MaxPrice,
Lastname
FROM
CTE
GROUP BY
CTE.Lastname
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT *
FROM (
SELECT TOP (1) WITH TIES CustomerLastName
FROM ranked
ORDER BY OrderLinePrice DESC
) s
ORDER BY CustomerLastName
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName,
RANK() OVER (ORDER BY SUM(ol.Amount * p.Price) DESC) AS rnk
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT CustomerLastName
FROM ranked
WHERE rnk = 1
ORDER BY CustomerLastName
如果您只对最高的总价感兴趣,RANK()
就足够了,但是如果您希望客户获得最高的n
总价,请使用densite\u RANK()
代替,并将条件从rnk=1
更改为rnk,首先,您考虑过使用显式联接吗?这可能只是口味的问题,但您可能会发现使用显式连接的查询比使用隐式连接(或“逗号”连接)的查询更清晰,如您的示例中所示
关于这个问题,你可以使用带领带的TOP(1),如下所示:
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
*
FROM
CTE
WHERE
CTE.OrderLinePrice=(SELECT MAX(CTE2.OrderLinePrice) FROM CTE AS CTE2)
;WITH CTE
AS
(
SELECT SUM(OrderLine.Amount * Product.Price) AS OrderLinePrice,
Orders.Id, Customer.Lastname
FROM OrderLine, Product, Orders, Customer
WHERE OrderLine.ProductId = Product.Id
AND Orders.Id = OrderLine.OrderId
AND Customer.Id = Orders.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT
MAX(OrderLinePrice) AS MaxPrice,
Lastname
FROM
CTE
GROUP BY
CTE.Lastname
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT *
FROM (
SELECT TOP (1) WITH TIES CustomerLastName
FROM ranked
ORDER BY OrderLinePrice DESC
) s
ORDER BY CustomerLastName
WITH ranked AS (
SELECT
SUM(ol.Amount * p.Price) AS OrderLinePrice,
o.Id,
c.Lastname AS CustomerLastName,
RANK() OVER (ORDER BY SUM(ol.Amount * p.Price) DESC) AS rnk
FROM OrderLine ol
INNER JOIN Product p ON p.Id = ol.ProductId
INNER JOIN Orders o ON o.Id = ol.OrderId
INNER JOIN Customer c ON c.Id = o.CustomerId
GROUP BY Orders.Id, Customer.Lastname
)
SELECT CustomerLastName
FROM ranked
WHERE rnk = 1
ORDER BY CustomerLastName
如果您只对最高的总价感兴趣,RANK()
就足够了,但是如果您希望客户获得最高的n
总价,请使用densite\u RANK()
,并将条件从rnk=1
更改为rnk您使用的是什么版本的sql server?我已经有一段时间没有使用sql了,但是如何“选择前1名金额(订单行金额…)?假设您只需要一个结果…我正在查找订单与最昂贵订单一样昂贵的客户列表(请参见编辑)您使用的是什么版本的sql server?我已经有一段时间没有使用sql了,但是“选择前1名金额(OrderLine.Amt…)怎么样?假设您只需要一个结果…我正在查找订单与最昂贵订单一样昂贵的客户列表(请参见编辑)几乎:)我需要订单最昂贵的人的姓名列表。因此,基本上我需要这个列表来获取最昂贵订单的价格,然后将该值作为分隔符发送给同一个查询..听起来效率很低:)那么您需要哪位客户。如果您像现在这样订购OrderLinePrice。您将获得该列表,您正在接受关于。或者你如何限制他们更多?我正在寻找订单价格等于最高价格的客户列表。这看起来像:选择t.CustomerLastName FROM(选择SUM(OrderLine.Amount*Product.price)作为OrderLinePrice,Orders.Id,Customer.Lastname作为CustomerLastName,来自OrderLine,Product,Orders,Customer,其中OrderLine.ProductId=Product.Id和Orders.Id=OrderLine.OrderId和Customer.Id=Orders.CustomerId按Orders.Id分组,Customer.Lastname)作为t,其中t.OrderLinePrice=(//查询以获取最昂贵订单的价格),但这似乎有点多余:)更新了答案。查看一下:)我需要拥有最昂贵订单的人员的姓名列表。因此,基本上我需要这个列表来获取最昂贵订单的价格,然后将该值作为分隔符发送给同一个查询..听起来效率很低:)那么您需要哪个客户。如果您像现在一样订购OrderLinePrice,您将获取您要查看的列表。或者如何限制它们?我正在查找订单价格等于最高价格的客户列表。该列表如下所示:选择t.CustomerLastName FROM(选择SUM(OrderLine.Amount*Product.price)作为OrderLinePrice,Orders.Id,Customer.Lastname作为CustomerLastName,来自OrderLine,Product,Orders,Customer,其中OrderLine.ProductId=Product.Id和Orders.Id=OrderLine.OrderId和Customer.Id=Orders.CustomerId按Orders.Id分组,Customer.Lastname)作为t,其中t.OrderLinePrice=(//查询以获取最昂贵订单的价格)但这似乎有些多余:)更新了答案。请查看