无法在具有聚合值的 HAVING 子句中使用来自子查询表连接的单值列

Posted

技术标签:

【中文标题】无法在具有聚合值的 HAVING 子句中使用来自子查询表连接的单值列【英文标题】:Unable to use single-valued column from subquery table join in HAVING clause with aggregate value 【发布时间】:2021-02-01 08:34:24 【问题描述】:

我提出这个问题的相关问题here

对于相关的表和列(比以下更多),我有一个带有 cust_idstate 列的 customer 表和一个带有 account_idcust_idaccount 表和avail_balance 列。

客户表示例:

| cust_id | state |
|--------:|-------|
|       1 | MA    |
|       2 | MA    |
|       3 | MA    |
|       4 | MA    |
|       5 | NH    |
|       6 | MA    |
|       7 | MA    |
|       8 | NH    |
|       9 | MA    |
|      10 | NH    |
|      11 | MA    |
|      12 | NH    |
|      13 | MA    |

示例帐户表:

| account_id | cust_id | avail_balance |
|-----------:|--------:|--------------:|
|          1 |       1 |       1057.75 |
|          2 |       1 |           500 |
|          3 |       1 |          3000 |
|          4 |       2 |       2258.02 |
|          5 |       2 |           200 |
|          7 |       3 |       1057.75 |
|          8 |       3 |        2212.5 |
|         10 |       4 |        534.12 |
|         11 |       4 |        767.77 |
|         12 |       4 |       5487.09 |
|         13 |       5 |       2237.97 |
|         14 |       6 |        122.37 |
|         15 |       6 |         10000 |
|         17 |       7 |          5000 |
|         18 |       8 |       3487.19 |
|         19 |       8 |        387.99 |
|         21 |       9 |        125.67 |
|         22 |       9 |       9345.55 |
|         23 |       9 |          1500 |
|         24 |      10 |      23575.12 |
|         25 |      10 |             0 |
|         27 |      11 |       9345.55 |
|         28 |      12 |      38552.05 |
|         29 |      13 |         50000 |

这是我希望执行的查询格式。

SELECT a.cust_id, SUM(a.avail_balance) AS cust_tot_bal
FROM
    account AS a
    INNER JOIN customer c ON a.cust_id = c.cust_id
    CROSS JOIN (SELECT MAX(cust_id) AS max_nh_cust_id, MAX(nh_cust_tot_bal) AS max_nh_cust_tot_bal
                FROM
                    (SELECT a.cust_id, SUM(avail_balance) AS nh_cust_tot_bal
                     FROM
                         account AS a
                         INNER JOIN customer c ON a.cust_id = c.cust_id
                     WHERE
                         c.state = 'NH'
                     GROUP BY a.cust_id) AS nh_cust_tot_bal) AS max_nh_cust_tot_bal_t
WHERE c.state = 'MA'
AND a.cust_id > max_nh_cust_id
GROUP BY a.cust_id;

这失败了,因为它无法从之前的加入中检测到max_nh_cust_tot_bal

上述示例数据的预期结果(cust_tot_bal 列是可选的):

| cust_id | cust_tot_bal |
|--------:|-------------:|
|      13 |        50000 |

【问题讨论】:

【参考方案1】:

您可以通过此查询获得最大cust_id 和州'NH' 的客户总数:

SELECT MAX(cust_id) max_nh_cust_id, 
       MAX(t.max_nh_avail_balance) max_nh_avail_balance
FROM (
  SELECT a.cust_id, SUM(a.avail_balance) AS max_nh_avail_balance
  FROM account a INNER JOIN customer c 
  ON a.cust_id = c.cust_id
  WHERE c.state = 'NH'
  GROUP BY a.cust_id
) t

你可以像这样加入它:

SELECT m.cust_id, m.cust_tot_bal
FROM (
  SELECT a.cust_id, SUM(a.avail_balance) AS cust_tot_bal
  FROM account a INNER JOIN customer c 
  ON a.cust_id = c.cust_id
  WHERE c.state = 'MA'
  GROUP BY a.cust_id
) m  
INNER JOIN (
  SELECT MAX(cust_id) max_nh_cust_id, 
         MAX(t.max_nh_avail_balance) max_nh_avail_balance
  FROM (
    SELECT a.cust_id, SUM(a.avail_balance) AS max_nh_avail_balance
    FROM account a INNER JOIN customer c 
    ON a.cust_id = c.cust_id
    WHERE c.state = 'NH'
    GROUP BY a.cust_id
  ) t 
) n ON m.cust_id > n.max_nh_cust_id AND m.cust_tot_bal > n.max_nh_avail_balance

请参阅demo。 结果

> cust_id | cust_tot_bal
> ------: | -----------:
>      13 |        50000

【讨论】:

道歉。我忘记添加上一个问题中的最大客户 ID 约束。该问题已相应更新。

以上是关于无法在具有聚合值的 HAVING 子句中使用来自子查询表连接的单值列的主要内容,如果未能解决你的问题,请参考以下文章

SQL - 聚合可能不会出现在 WHERE 子句中,除非它位于 HAVING 子句中包含的子查询中

SQL HAVING 子句

为啥聚合函数不能放在where后面?

SQL HAVING 子句

JPA Group by 具有多个字段

Having子句的构成要素