如何在 SQL 中 convert/fix 这条 WITH 语句?

How can I convert/fix this WITH statement in SQL?

我有这个查询,但显然 WITH 语句尚未在某些数据库系统中实现。我如何重写此查询以获得相同的结果。

基本上这个查询应该做的是提供数据库中存款总额小于所有分支加起来的平均值的所有分支的分支名称。

WITH branch_total (branch_name, value) AS 
SELECT branch_name, sum (balance) FROM account
GROUP BY branch_name
WITH branch_total_avg (value) AS SELECT avg(value)
FROM branch_total SELECT branch_name
FROM branch_total, branch_total_avg
WHERE branch_total.value < branch_total_avg.value;

没有 WITH 可以用其他方式写吗?请帮忙。

WITH 语法是作为 MySQL 8.0 的新功能引入的。您已经注意到 MySQL 的早期版本不支持它。如果您无法升级到 MySQL 8.0,则必须使用如下子查询重写查询:

SELECT branch_total.branch_name
FROM (
  SELECT branch_name, SUM(balance) AS value FROM account
  GROUP BY branch_name
) AS branch_total
CROSS JOIN (
  SELECT AVG(value) AS value FROM (
    SELECT SUM(balance) AS value FROM account GROUP BY branch_name 
  ) AS sums
) AS branch_total_avg
WHERE branch_total.value < branch_total_avg.value;

在这种情况下,WITH语法没有任何优势,所以你还不如这样写。

另一种可能更有效的方法是将其拆分为两个查询,因为它可能避免在查询中使用临时表:

  SELECT AVG(value) INTO @avg FROM (
    SELECT SUM(balance) AS value FROM account GROUP BY branch_name
  ) AS sums;

  SELECT branch_name, SUM(balance) AS value FROM account
  GROUP BY branch_name
  HAVING value < @avg;

这种方法当然更易于阅读和调试,并且编写更直接的代码有一些优势,可以让更多开发人员维护它而无需 post 在 Stack Overflow 上寻求帮助。

重写此查询的另一种方法:

SELECT branch_name
  FROM account
 GROUP BY branch_name
HAVING SUM(balance) < (SELECT AVG(value) 
                         FROM (SELECT branch_name, SUM(balance) AS value
                                 FROM account
                                GROUP BY branch_name) t1)

正如您从这段代码中看到的那样,帐户 table 有两次几乎相同的聚合查询 运行,一次在外层,一次嵌套两层。

WITH 子句的好处是您可以编写该聚合查询,一次为其命名并根据需要多次使用它。此外,智能数据库引擎只会 运行 该次级查询一次,但会根据需要经常使用结果。