假设我有一张付款表:
PaymentID INT, CustomerID INT, 价值INT, 付费日期
我想针对每个客户的最高付款运行查询。这是否可以使用单个SQL查询,以避免挖掘我不感兴趣的每一行 - 或者更糟糕的是,为每个客户运行查询?
到目前为止,我想出的最好的是:
SELECT CustomerID,MAX(Value)FROM Payments GROUP BY CustomerID;
但是这并没有给我找到的行的PaymentId或PaidOn值。
答案 0 :(得分:10)
select PaymentID, CustomerID, Value, PaidOn
from payments
where (customerID, value) in
( select customerID, max(value)
from payments
group by customerID
);
请注意,如果每个客户有多个具有最大值的付款,则每个客户可以返回多个行。
答案 1 :(得分:4)
这与今天早些时候的this one完全相同。
要避免子查询,您还可以使用:
SELECT
P1.PaymentID,
P1.CustomerID,
P1.Value,
P1.PaidOn
FROM
Payments P1
LEFT OUTER JOIN Payments P2 ON
P2.CustomerID = P1.CustomerID AND
P2.Value > P1.Value
WHERE
P2.PaymentID IS NULL
根据您关于价值关系的业务规则,您需要更改此查询。
例如,如果存在平局,则使用最新付款:
SELECT
P1.PaymentID,
P1.CustomerID,
P1.Value,
P1.PaidOn
FROM
Payments P1
LEFT OUTER JOIN Payments P2 ON
P2.CustomerID = P1.CustomerID AND
(P2.Value > P1.Value OR (P2.Value = P1.Value AND P2.PaidOn > P1.PaidOn))
WHERE
P2.PaymentID IS NULL
答案 2 :(得分:2)
以下查询将实现此目的。它会拉出没有更大值的所有行。
SELECT *
FROM payments p
WHERE NOT EXISTS (
SELECT *
FROM payments p2
WHERE p2.CustomerID = p.CustomerId
AND p2.Value > p.Value
)
答案 3 :(得分:0)
再使用自我加入 - 语法糖的问题。更容易理解和更好的性能。
select PaymentID, CustomerID, Value, PaidOn
from
( select customerID, max(value) as maxValue
from payments
group by customerID
)as T
INNER JOIN payments as P
ON P.Value=T.maxValue AND P.CustomerID = T.CustomerID
-Maulik Modi
答案 4 :(得分:0)
这是一个选项,它使用派生表:
SELECT p2.PaymentId, p2.CustomerID, p2.Value, p2.PaidOn
FROM Payments AS p2 INNER JOIN
(SELECT CustomerID, MAX(Value) AS Value
FROM Payments
GROUP BY CustomerID)
AS p1
ON p1.CustomerID = p2.CustomerID AND p1.Value = p2.Value