用于查找表中的代表行的SQL查询

时间:2008-12-17 17:03:39

标签: sql

假设我有一张付款表:

PaymentID INT, CustomerID INT, 价值INT, 付费日期

我想针对每个客户的最高付款运行查询。这是否可以使用单个SQL查询,以避免挖掘我不感兴趣的每一行 - 或者更糟糕的是,为每个客户运行查询?

到目前为止,我想出的最好的是:

SELECT CustomerID,MAX(Value)FROM Payments GROUP BY CustomerID;

但是这并没有给我找到的行的PaymentId或PaidOn值。

5 个答案:

答案 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