在MySQL中,如何使用WITH替换变量?

In MySQL, how can you replace variables by using WITH?

我有一个将报表余额与费用记录进行比较的查询。

我想让它成为一个视图,但它使用了两个变量,您不能在视图中使用它们。

我想到应该可以使用通用 Table 表达式(CTE 或“WITH”查询)来替换变量,这样我就可以将其打包为视图.

我读到 CTE 可以用作一种命名子查询,然后可以在同一查询中重复使用。我玩过,试图让它工作,但无法摆脱语法错误。

以下是我正在使用的带有变量的代码,但如果有一个概念工具箱以一般方式执行此操作,而不是简单地解决我的问题,那就太好了! :-)

SELECT
  sb.id,
  Account,
  acct_name(Account) AS `Name`,
--    acct_name() is a recursive CTE that I wrote to display the name of a
--    hierarchical account name, such as "Assets, Current Assets, Chequing".
  `Begin`,
  Begin_balance,
  `End`,
  End_balance,
  sb.amount `Change`,
  @sss := COALESCE(
    (SELECT SUM(Amount)
        FROM sa_general_journal jg1
        WHERE (sb.id IN(jg1.Statement_s, jg1.Statement_d))
            AND sb.account = jg1.Source),
    0) AS `Src`,
  @ddd := COALESCE(
    (SELECT SUM(Amount)
        FROM sa_general_journal jg2
        WHERE (sb.id IN(jg2.Statement_s, jg2.Statement_d))
            AND sb.account = jg2.Destination),
    0) AS `Dst`,
  CONVERT(@ddd - @sss, DECIMAL (8,2)) AS `Dest-Src`,
  IF(CONVERT(@ddd - @sss - sb.amount, DECIMAL (8,2)) = 0,
    NULL,
    CONVERT(@ddd - @sss - sb.amount, DECIMAL (8,2))) AS `Error`
FROM sa_statement_balances sb
    LEFT JOIN sa_accounts a ON Account = a.ID
# WHERE `Begin` >= '2020-07-01'
GROUP BY sb.id DESC
ORDER BY BEGIN

我试过更换

  @sss := COALESCE(…, 0) AS `Src`,

  COALESCE(WITH sss AS (
    SELECT SUM(Amount)
      FROM sa_general_journal jg1
      WHERE (sb.id IN(jg1.Statement_s, jg1.Statement_d))
        AND sb.account = jg1.Source) SELECT * from sss), 0) AS `Src`,

但我得到的只是一个令人沮丧的语法错误。

有没有关于用 CTE 替换变量的通用方法的想法,尤其是可以解决我的特定问题的方法?

谢谢!

测试

WITH cte AS (
SELECT sb.id,
       Account,
       acct_name(Account) AS `Name`,
       `Begin`,
       Begin_balance,
       `End`,
       End_balance,
       sb.amount `Change`,
       COALESCE((SELECT SUM(Amount)
                 FROM sa_general_journal jg1
                 WHERE (sb.id IN(jg1.Statement_s, jg1.Statement_d))
                   AND sb.account = jg1.Source),0) AS `Src`,
       COALESCE((SELECT SUM(Amount)
                 FROM sa_general_journal jg2
                 WHERE (sb.id IN(jg2.Statement_s, jg2.Statement_d))
                   AND sb.account = jg2.Destination),0) AS `Dst`,
       sb.amount
FROM sa_statement_balances sb
LEFT JOIN sa_accounts a ON Account = a.ID
# WHERE `Begin` >= '2020-07-01'
GROUP BY sb.id DESC
)
SELECT id,
       Account,
       `Name`,
       `Begin`,
       Begin_balance,
       `End`,
       End_balance,
       `Change`,
       `Src`,
       `Dst`,
       CONVERT(`Dst` - `Src`, DECIMAL (8,2)) AS `Dest-Src`,
       IF(CONVERT(`Dst` - `Src` - amount, DECIMAL (8,2)) = 0,
          NULL,
          CONVERT(`Dst` - `Src` - amount, DECIMAL (8,2))) AS `Error`
FROM cte
ORDER BY `BEGIN`