PAYATHON 2026

SQL:使用 Sub Query 查询大于多个 Vendor 最大付款的记录

支付阿杰

结论

把子查询中的 VendorID = 34 改为 VendorID IN (34, 35, 83),再通过 MAX() 取出这三个 Vendor 的最高付款金额:

SELECT VendorID, PaymentTotal
FROM Invoices
WHERE PaymentTotal > (
    SELECT MAX(PaymentTotal)
    FROM Invoices
    WHERE VendorID IN (34, 35, 83)
);

查询会返回 PaymentTotal 严格大于 VendorID 34、35、83 所有付款记录中最高金额的记录,同时显示对应的 VendorID 和 PaymentTotal。

原因

原查询的子查询只有一个筛选条件:

WHERE VendorID = 34

所以外层查询仅以 VendorID 34 的付款记录作为比较对象,没有计算 VendorID 35 和 83 的数据。

使用 IN 可以一次筛选多个 Vendor:

WHERE VendorID IN (34, 35, 83)

MAX(PaymentTotal) 随后从这些 Vendor 的所有付款记录中取出最大值,外层查询再逐条判断付款金额是否高于这个值。

使用 ALL 的写法

如果题目明确要求使用 ALL,可以保留原有结构:

SELECT VendorID, PaymentTotal
FROM Invoices
WHERE PaymentTotal > ALL (
    SELECT PaymentTotal
    FROM Invoices
    WHERE VendorID IN (34, 35, 83)
);

当子查询返回的付款金额均不为 NULL 时:

PaymentTotal > ALL (子查询结果)

表示 PaymentTotal 必须大于子查询返回的每一个值,效果等同于大于其中的最大值。

相比之下,MAX() 的写法更直观:先求出最高付款金额,再进行一次标量比较。

是否排除 34、35 和 83

上述查询会检查 Invoices 表中的所有记录。VendorID 34、35、83 的付款通常不可能高于其所在集合的最大值,但如果业务规则要求明确排除这三个 Vendor,可以在外层查询中增加条件:

SELECT VendorID, PaymentTotal
FROM Invoices
WHERE VendorID NOT IN (34, 35, 83)
  AND PaymentTotal > (
      SELECT MAX(PaymentTotal)
      FROM Invoices
      WHERE VendorID IN (34, 35, 83)
  );

注意事项

如果 PaymentTotal 允许为 NULL,建议优先使用 MAX()。聚合函数 MAX() 会忽略 NULL,而 > ALL 的子查询只要包含 NULL,SQL 的三值逻辑就可能使比较结果变为未知,导致查询无法返回预期记录。

如果表中完全没有 VendorID 34、35、83 的付款记录,MAX() 会返回 NULL。此时:

PaymentTotal > NULL

不会匹配任何记录。如果业务上需要为“没有基准付款”的情况设置默认值,可以根据数据库类型使用 COALESCE,例如:

SELECT VendorID, PaymentTotal
FROM Invoices
WHERE PaymentTotal > COALESCE(
    (
        SELECT MAX(PaymentTotal)
        FROM Invoices
        WHERE VendorID IN (34, 35, 83)
    ),
    0
);

这里使用 0 有两个前提:付款金额不会为负,并且业务上可以把“没有付款记录”视为最大值为 0。否则,应按照实际业务规则设置处理方式。

备注:内容仅供参考。