在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`
我有一个将报表余额与费用记录进行比较的查询。
我想让它成为一个视图,但它使用了两个变量,您不能在视图中使用它们。
我想到应该可以使用通用 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`