SQL 会计系统中的分层汇总
Hierarchical roll-up in SQL accounting system
我正在尝试根据会计系统中的一般日记账分录制作年度报告(余额 Sheet 和损益)。
普通期刊table(简体)包括:
CREATE TABLE `sa_general_journal` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Date` timestamp NOT NULL DEFAULT current_timestamp(),
`Item` varchar(1024) NOT NULL DEFAULT '',
`Amount` decimal(9,2) NOT NULL DEFAULT 0.00,
`Source` int(10) unsigned NOT NULL,
`Destination` int(10) unsigned NOT NULL,
PRIMARY KEY (`ID`),
KEY `Date` (`Date`),
KEY `Source` (`Source`),
KEY `Destination` (`Destination`),
CONSTRAINT `sa_credit-account` FOREIGN KEY (`Destination`) REFERENCES `sa_accounts` (`ID`),
CONSTRAINT `sa_debit-account` FOREIGN KEY (`Source`) REFERENCES `sa_accounts` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=21561 DEFAULT CHARSET=utf8;
其中 Amount
通常(但不一定)是无符号的,并且是从 Source
帐户或类别转移到 Destination
类别的金额。
会计科目表(简体)包括:
CREATE TABLE `sa_accounts` (
`ID` int(10) unsigned NOT NULL,
`Super` int(10) unsigned,
`Name` varchar(255) NOT NULL,
`Type` enum('Asset','Liability','Income','Expense'),
`Report` enum('BS','PL'), -- for "Balance Sheet" or "Profit & Loss"
PRIMARY KEY (`ID`),
KEY `Super` (`Super`),
CONSTRAINT `Super` FOREIGN KEY (`Super`) REFERENCES `sa_accounts` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
其中 ID
是介于 1,000,000 和 8,999,999 之间的七位整数,未分配资金单独输入零。
可被 1,000,000 整除的帐户 ID
是典型 GAAP 编号帐户方案中的 "top level" 个帐户:
INSERT INTO sa_account (`ID`, `Super`, `Name`, `Type`, `Report`)
VALUES
(0, NULL, "Not yet allocated", NULL, NULL),
(1000000, NULL, "Assets", "Asset", "BS"),
(2000000, NULL, "Liabilities", "Liability", "BS"),
(3000000, NULL, "Equity", "Liability", "BS"),
(4000000, NULL, "Income", "Income", "PL"),
(5000000, NULL, "Expenses", "Expense", "PL"),
(6000000, NULL, "Operating Expenses", "Expense", "PL"),
(7000000, NULL, "Other Expenses", "Expense", "PL"),
(8000000, NULL, "Other Income", "Income", "PL");
这些汇总帐户是抽象的,通常(但不一定)没有实际分配给它们的任何内容。相反,子账户收到实际分配:
INSERT INTO sa_account (`ID`, `Super`, `Name`, `Type`, `Report`)
VALUES
(1010000, 1000000, "Cash", "Asset", "BS"),
(1010001, 1010000, "Cash", "Asset", "BS"),
(1010011, 1010000, "Chequing", "Asset", "BS"),
(1019999, 1010000, "Test bank account", "Asset", "BS"),
-- ...
(2100000, 2000000, "Accounts Payable", "Liability", "BS"),
(2050000, 2100000, "Lines of credit", "Liability", "BS"),
(2052008, 2050000, "Mastercard -2008", "Liability", "BS"),
(2054710, 2050000, "Visa -4710", "Liability", "BS"),
-- ...
(3200000, 3000000, "Shareholder Equity", "Liability", "BS"),
(3300000, 3000000, "Rent to own", "Liability", "BS"),
-- ...
(4050000, 4000000, "Dairy income", "Income", "PL"),
(4050001, 4050000, "Animals sold", "Income", "PL"),
(4050002, 4050000, "Milk sold", "Income", "PL"),
(4050003, 4050000, "Cheese sold", "Income", "PL"),
(4059999, 4050000, "Test income source", "Income", "PL"),
-- ...
(5050000, 5000000, "Dairy expense", "Expense", "PL"),
(5050001, 5000000, "Animals bought", "Expense", "PL"),
(5050002, 5000000, "Feed bought", "Expense", "PL"),
(5059999, 5000000, "Test expense destination", "Expense", "PL");
-- ...
这些子帐户(通过 Super
)引用具有层次关系的其他帐户。请注意,顶级帐户在 Super
列中为 NULL。
下面是一些测试一般日记条目:
INSERT INTO sa_general_journal (`ID`, `Date`, `Item`, `Amount`, `Source`, `Destination`)
VALUES (NULL, "2020-05-03", "Test income transaction", 10.10, 4059999, 1009999),
(NULL, "2020-05-03", "Test expense transaction", 1.01, 1009999, 5059999);
在Nick, I was able to 的帮助下,使用以下代码:
WITH CTE1 AS (
SELECT
Source AS account,
0 AS TYPE,
-Amount AS Amount
FROM sa_general_journal
UNION ALL
SELECT
Destination,
1,
Amount
FROM sa_general_journal gj
)
SELECT
acc.ID `Account`,
acc.Super,
acc.Name,
SUM(CASE WHEN CTE1.type = 0 THEN Amount END) AS Debits,
SUM(CASE WHEN CTE1.type = 1 THEN Amount END) AS Credits,
SUM(Amount) AS Net
FROM CTE1
JOIN sa_accounts acc ON CTE1.account = acc.ID
-- WHERE acc.Report = "BS"
-- WHERE acc.Report = "PL"
GROUP BY acc.ID
到目前为止,一切顺利!这对我理解如何使用常见 Table 表达式有很大帮助!
但是现在,我想 "roll up" 子账户到抽象账户中,给出类似这样的期望结果:
<table>
<th>ID</th><th>Name</th><th>Debits</th><th>Credits</th><th>Net</th><th></th><th></th></tr>
<tr><td>1000000</td><td>Cash</td><td>-1.01</td><td>10.10</td><td>9.09</td><td></td><td></td></tr>
<tr><td>1009999</td><td>Cash -> Test chequing account</td><td>-1.01</td><td>10.10</td><td></td><td></td><td>9.09</td></tr>
<tr><td>4000000</td><td>Income</td><td>-10.10</td><td><i>NULL</i></td><td>-10.10</td><td></td><td></td></tr>
<tr><td>4050000</td><td>Income -> Dairy Income</td><td>-10.10</td><td><i>NULL</i></td><td></td><td>-10.10</td><td></td></tr>
<tr><td>4059999</td><td>Income -> Dairy Income -> Test income transaction</td><td>-10.10</td><td><i>NULL</i></td><td></td><td></td><td>-10.10</td></tr>
<tr><td>5000000</td><td>Expenses</td><td>-10.10</td><td><i>NULL</i></td><td>-10.10</td><td></td><td></td></tr>
<tr><td>5050000</td><td>Expenses -> Dairy Expenses</td><td>-10.10</td><td><i>NULL</i></td><td></td><td>-10.10</td><td></td></tr>
<tr><td>5059999</td><td>Expenses -> Dairy Expenses -> Test expense transaction</td><i>NULL</i></td><td>1.01</td><td></td><td></td><td>1.01</td></tr>
</table>
在几次错误的开始之后,我想出了以下天真的想法,即简单地将 WITH RECURSIVE 包装在上面的代码周围,但汇总具有相同 Super
列的子帐户:
WITH RECURSIVE CTE2 AS
(WITH CTE1 AS (
SELECT
Source AS account,
0 AS TYPE,
-Amount AS Amount
FROM sa_general_journal
UNION ALL
SELECT
Destination,
1,
Amount
FROM sa_general_journal gj
)
SELECT
acc.ID `Account`,
acc.Super,
acc.Name,
SUM(CASE WHEN CTE1.type = 0 THEN Amount END) AS Debits,
SUM(CASE WHEN CTE1.type = 1 THEN Amount END) AS Credits,
SUM(Amount) AS Net
FROM CTE1
JOIN sa_accounts acc ON CTE1.account = acc.ID
-- WHERE acc.Report = "BS"
-- WHERE acc.Report = "BS"
GROUP BY acc.ID
UNION ALL
SELECT
Name,
SUM(CTE2.Debits),
SUM(CTE2.Credits),
SUM(CTE2.Net)
FROM CTE2
WHERE CTE2.`Super` IS NOT NULL)
SELECT * FROM CTE2
我知道最后一个 SELECT 有问题;正如我所说,这是我的第一次尝试,但我似乎 运行 遇到了一个 insurmountable 障碍。
当执行前面的代码时,我得到 "Query Failed. Restrictions imposed on recursive definitions are violated for table 'CTE2. Error code 4008." 经过大量搜索才发现聚合查询(SUM 等)在此类查询的递归部分中是不允许的。叹息
我读过 WITH RECURSIVE,SQL 变得与图灵兼容,所以一定可以做我正在寻找的事情,但是在递归查询中没有 SUM(),很难想象一下如何解决这个问题!
此查询应该会为您提供所需的结果。它基于对您上一个问题的回答,添加了一个递归 CTE,该 CTE 将每笔交易复制到层次结构中位于其上方的所有帐户。然后在最终查询中汇总每个帐户的值:
WITH RECURSIVE xfers AS (
SELECT Source AS account,
0 AS TYPE,
-Amount AS Amount
FROM sa_general_journal
UNION ALL
SELECT Destination,
1,
Amount
FROM sa_general_journal gj
),
dbcr AS (
SELECT
acc.ID `Account`,
acc.Super,
acc.Name,
COALESCE(SUM(CASE WHEN x.type = 0 THEN Amount END), 0) AS Debits,
COALESCE(SUM(CASE WHEN x.type = 1 THEN Amount END), 0) AS Credits,
COALESCE(SUM(Amount), 0) AS Net
FROM sa_accounts acc
LEFT JOIN xfers x ON x.account = acc.ID
-- WHERE acc.Report = "BS"
-- WHERE acc.Report = "PL"
GROUP BY acc.ID
),
summary AS (
SELECT *
FROM dbcr
WHERE Net != 0
UNION ALL
SELECT d.Account, d.Super, d.Name, s.Debits, s.Credits, s.Net
FROM dbcr d
JOIN summary s ON d.Account = s.Super
WHERE s.Super IS NOT NULL
)
SELECT Account, Super, Name,
SUM(Debits) AS Debits,
SUM(Credits) AS Credits,
SUM(Net) AS Net
FROM summary
GROUP BY Account, Super, Name
ORDER BY Account
输出(对于我的扩展演示):
Account Super Name Debits Credits Net
1000000 null Assets -6.31 10.1 3.79
1010000 1000000 Cash -6.31 10.1 3.79
1010011 1010000 Chequing -5.3 0 -5.3
1019999 1010000 Test bank account -1.01 10.1 9.09
4000000 null Income -10.1 0 -10.1
4050000 4000000 Dairy income -10.1 0 -10.1
4059999 4050000 Test income source -10.1 0 -10.1
5000000 null Expenses 0 6.31 6.31
5050002 5000000 Feed bought 0 5.3 5.3
5059999 5000000 Test expense dest 0 1.01 1.01
受到上面分析 Nick 的回答的启发,我对 WITH RECURSIVE 的了解越来越多!
这是我为各种帐户制作分层名称的功能。 Nick 的优秀答案中使用 Name
的任何地方,现在都可以使用 acct_name(ID
) 来获取分层名称路径。
CREATE DEFINER=`root`@`10.1.2.%` FUNCTION `acct_name`(a int(10)) RETURNS varchar(253) CHARSET utf8
READS SQL DATA
DETERMINISTIC
RETURN
(WITH RECURSIVE acct_names AS (
SELECT id, Super, Name, Name AS Path FROM sa_accounts WHERE ID = a
UNION ALL
SELECT
sup.ID,
sup.Super,
sup.Name,
CONCAT(sup.Name, ', ', acct_names.Path)
FROM acct_names
LEFT JOIN sa_accounts sup ON acct_names.Super = sup.ID
WHERE sup.ID IS NOT NULL
)
SELECT Path FROM acct_names WHERE `Super` IS NULL);
现在,示例数据将导致:
Account Super Name Debits Credits Net
1000000 null Assets -6.31 10.1 3.79
1010000 1000000 Assets, Cash -6.31 10.1 3.79
1010011 1010000 Assets, Cash, Chequing -5.3 0 -5.3
1019999 1010000 Assets, Cash, Test bank account -1.01 10.1 9.09
4000000 null Income -10.1 0 -10.1
4050000 4000000 Income, Dairy income -10.1 0 -10.1
4059999 4050000 Income, Dairy income, Test income source -10.1 0 -10.1
5000000 null Expenses 0 6.31 6.31
5050002 5000000 Expenses, Feed bought 0 5.3 5.3
5059999 5000000 Expenses, Test expense dest 0 1.01 1.01
(如果这个答案不合适,我深表歉意。我在评论部分没有看到 post 格式化代码的任何方法。)
我正在尝试根据会计系统中的一般日记账分录制作年度报告(余额 Sheet 和损益)。
普通期刊table(简体)包括:
CREATE TABLE `sa_general_journal` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Date` timestamp NOT NULL DEFAULT current_timestamp(),
`Item` varchar(1024) NOT NULL DEFAULT '',
`Amount` decimal(9,2) NOT NULL DEFAULT 0.00,
`Source` int(10) unsigned NOT NULL,
`Destination` int(10) unsigned NOT NULL,
PRIMARY KEY (`ID`),
KEY `Date` (`Date`),
KEY `Source` (`Source`),
KEY `Destination` (`Destination`),
CONSTRAINT `sa_credit-account` FOREIGN KEY (`Destination`) REFERENCES `sa_accounts` (`ID`),
CONSTRAINT `sa_debit-account` FOREIGN KEY (`Source`) REFERENCES `sa_accounts` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=21561 DEFAULT CHARSET=utf8;
其中 Amount
通常(但不一定)是无符号的,并且是从 Source
帐户或类别转移到 Destination
类别的金额。
会计科目表(简体)包括:
CREATE TABLE `sa_accounts` (
`ID` int(10) unsigned NOT NULL,
`Super` int(10) unsigned,
`Name` varchar(255) NOT NULL,
`Type` enum('Asset','Liability','Income','Expense'),
`Report` enum('BS','PL'), -- for "Balance Sheet" or "Profit & Loss"
PRIMARY KEY (`ID`),
KEY `Super` (`Super`),
CONSTRAINT `Super` FOREIGN KEY (`Super`) REFERENCES `sa_accounts` (`ID`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
其中 ID
是介于 1,000,000 和 8,999,999 之间的七位整数,未分配资金单独输入零。
可被 1,000,000 整除的帐户 ID
是典型 GAAP 编号帐户方案中的 "top level" 个帐户:
INSERT INTO sa_account (`ID`, `Super`, `Name`, `Type`, `Report`)
VALUES
(0, NULL, "Not yet allocated", NULL, NULL),
(1000000, NULL, "Assets", "Asset", "BS"),
(2000000, NULL, "Liabilities", "Liability", "BS"),
(3000000, NULL, "Equity", "Liability", "BS"),
(4000000, NULL, "Income", "Income", "PL"),
(5000000, NULL, "Expenses", "Expense", "PL"),
(6000000, NULL, "Operating Expenses", "Expense", "PL"),
(7000000, NULL, "Other Expenses", "Expense", "PL"),
(8000000, NULL, "Other Income", "Income", "PL");
这些汇总帐户是抽象的,通常(但不一定)没有实际分配给它们的任何内容。相反,子账户收到实际分配:
INSERT INTO sa_account (`ID`, `Super`, `Name`, `Type`, `Report`)
VALUES
(1010000, 1000000, "Cash", "Asset", "BS"),
(1010001, 1010000, "Cash", "Asset", "BS"),
(1010011, 1010000, "Chequing", "Asset", "BS"),
(1019999, 1010000, "Test bank account", "Asset", "BS"),
-- ...
(2100000, 2000000, "Accounts Payable", "Liability", "BS"),
(2050000, 2100000, "Lines of credit", "Liability", "BS"),
(2052008, 2050000, "Mastercard -2008", "Liability", "BS"),
(2054710, 2050000, "Visa -4710", "Liability", "BS"),
-- ...
(3200000, 3000000, "Shareholder Equity", "Liability", "BS"),
(3300000, 3000000, "Rent to own", "Liability", "BS"),
-- ...
(4050000, 4000000, "Dairy income", "Income", "PL"),
(4050001, 4050000, "Animals sold", "Income", "PL"),
(4050002, 4050000, "Milk sold", "Income", "PL"),
(4050003, 4050000, "Cheese sold", "Income", "PL"),
(4059999, 4050000, "Test income source", "Income", "PL"),
-- ...
(5050000, 5000000, "Dairy expense", "Expense", "PL"),
(5050001, 5000000, "Animals bought", "Expense", "PL"),
(5050002, 5000000, "Feed bought", "Expense", "PL"),
(5059999, 5000000, "Test expense destination", "Expense", "PL");
-- ...
这些子帐户(通过 Super
)引用具有层次关系的其他帐户。请注意,顶级帐户在 Super
列中为 NULL。
下面是一些测试一般日记条目:
INSERT INTO sa_general_journal (`ID`, `Date`, `Item`, `Amount`, `Source`, `Destination`)
VALUES (NULL, "2020-05-03", "Test income transaction", 10.10, 4059999, 1009999),
(NULL, "2020-05-03", "Test expense transaction", 1.01, 1009999, 5059999);
在Nick, I was able to
WITH CTE1 AS (
SELECT
Source AS account,
0 AS TYPE,
-Amount AS Amount
FROM sa_general_journal
UNION ALL
SELECT
Destination,
1,
Amount
FROM sa_general_journal gj
)
SELECT
acc.ID `Account`,
acc.Super,
acc.Name,
SUM(CASE WHEN CTE1.type = 0 THEN Amount END) AS Debits,
SUM(CASE WHEN CTE1.type = 1 THEN Amount END) AS Credits,
SUM(Amount) AS Net
FROM CTE1
JOIN sa_accounts acc ON CTE1.account = acc.ID
-- WHERE acc.Report = "BS"
-- WHERE acc.Report = "PL"
GROUP BY acc.ID
到目前为止,一切顺利!这对我理解如何使用常见 Table 表达式有很大帮助!
但是现在,我想 "roll up" 子账户到抽象账户中,给出类似这样的期望结果:
<table>
<th>ID</th><th>Name</th><th>Debits</th><th>Credits</th><th>Net</th><th></th><th></th></tr>
<tr><td>1000000</td><td>Cash</td><td>-1.01</td><td>10.10</td><td>9.09</td><td></td><td></td></tr>
<tr><td>1009999</td><td>Cash -> Test chequing account</td><td>-1.01</td><td>10.10</td><td></td><td></td><td>9.09</td></tr>
<tr><td>4000000</td><td>Income</td><td>-10.10</td><td><i>NULL</i></td><td>-10.10</td><td></td><td></td></tr>
<tr><td>4050000</td><td>Income -> Dairy Income</td><td>-10.10</td><td><i>NULL</i></td><td></td><td>-10.10</td><td></td></tr>
<tr><td>4059999</td><td>Income -> Dairy Income -> Test income transaction</td><td>-10.10</td><td><i>NULL</i></td><td></td><td></td><td>-10.10</td></tr>
<tr><td>5000000</td><td>Expenses</td><td>-10.10</td><td><i>NULL</i></td><td>-10.10</td><td></td><td></td></tr>
<tr><td>5050000</td><td>Expenses -> Dairy Expenses</td><td>-10.10</td><td><i>NULL</i></td><td></td><td>-10.10</td><td></td></tr>
<tr><td>5059999</td><td>Expenses -> Dairy Expenses -> Test expense transaction</td><i>NULL</i></td><td>1.01</td><td></td><td></td><td>1.01</td></tr>
</table>
在几次错误的开始之后,我想出了以下天真的想法,即简单地将 WITH RECURSIVE 包装在上面的代码周围,但汇总具有相同 Super
列的子帐户:
WITH RECURSIVE CTE2 AS
(WITH CTE1 AS (
SELECT
Source AS account,
0 AS TYPE,
-Amount AS Amount
FROM sa_general_journal
UNION ALL
SELECT
Destination,
1,
Amount
FROM sa_general_journal gj
)
SELECT
acc.ID `Account`,
acc.Super,
acc.Name,
SUM(CASE WHEN CTE1.type = 0 THEN Amount END) AS Debits,
SUM(CASE WHEN CTE1.type = 1 THEN Amount END) AS Credits,
SUM(Amount) AS Net
FROM CTE1
JOIN sa_accounts acc ON CTE1.account = acc.ID
-- WHERE acc.Report = "BS"
-- WHERE acc.Report = "BS"
GROUP BY acc.ID
UNION ALL
SELECT
Name,
SUM(CTE2.Debits),
SUM(CTE2.Credits),
SUM(CTE2.Net)
FROM CTE2
WHERE CTE2.`Super` IS NOT NULL)
SELECT * FROM CTE2
我知道最后一个 SELECT 有问题;正如我所说,这是我的第一次尝试,但我似乎 运行 遇到了一个 insurmountable 障碍。
当执行前面的代码时,我得到 "Query Failed. Restrictions imposed on recursive definitions are violated for table 'CTE2. Error code 4008." 经过大量搜索才发现聚合查询(SUM 等)在此类查询的递归部分中是不允许的。叹息
我读过 WITH RECURSIVE,SQL 变得与图灵兼容,所以一定可以做我正在寻找的事情,但是在递归查询中没有 SUM(),很难想象一下如何解决这个问题!
此查询应该会为您提供所需的结果。它基于对您上一个问题的回答,添加了一个递归 CTE,该 CTE 将每笔交易复制到层次结构中位于其上方的所有帐户。然后在最终查询中汇总每个帐户的值:
WITH RECURSIVE xfers AS (
SELECT Source AS account,
0 AS TYPE,
-Amount AS Amount
FROM sa_general_journal
UNION ALL
SELECT Destination,
1,
Amount
FROM sa_general_journal gj
),
dbcr AS (
SELECT
acc.ID `Account`,
acc.Super,
acc.Name,
COALESCE(SUM(CASE WHEN x.type = 0 THEN Amount END), 0) AS Debits,
COALESCE(SUM(CASE WHEN x.type = 1 THEN Amount END), 0) AS Credits,
COALESCE(SUM(Amount), 0) AS Net
FROM sa_accounts acc
LEFT JOIN xfers x ON x.account = acc.ID
-- WHERE acc.Report = "BS"
-- WHERE acc.Report = "PL"
GROUP BY acc.ID
),
summary AS (
SELECT *
FROM dbcr
WHERE Net != 0
UNION ALL
SELECT d.Account, d.Super, d.Name, s.Debits, s.Credits, s.Net
FROM dbcr d
JOIN summary s ON d.Account = s.Super
WHERE s.Super IS NOT NULL
)
SELECT Account, Super, Name,
SUM(Debits) AS Debits,
SUM(Credits) AS Credits,
SUM(Net) AS Net
FROM summary
GROUP BY Account, Super, Name
ORDER BY Account
输出(对于我的扩展演示):
Account Super Name Debits Credits Net
1000000 null Assets -6.31 10.1 3.79
1010000 1000000 Cash -6.31 10.1 3.79
1010011 1010000 Chequing -5.3 0 -5.3
1019999 1010000 Test bank account -1.01 10.1 9.09
4000000 null Income -10.1 0 -10.1
4050000 4000000 Dairy income -10.1 0 -10.1
4059999 4050000 Test income source -10.1 0 -10.1
5000000 null Expenses 0 6.31 6.31
5050002 5000000 Feed bought 0 5.3 5.3
5059999 5000000 Test expense dest 0 1.01 1.01
受到上面分析 Nick 的回答的启发,我对 WITH RECURSIVE 的了解越来越多!
这是我为各种帐户制作分层名称的功能。 Nick 的优秀答案中使用 Name
的任何地方,现在都可以使用 acct_name(ID
) 来获取分层名称路径。
CREATE DEFINER=`root`@`10.1.2.%` FUNCTION `acct_name`(a int(10)) RETURNS varchar(253) CHARSET utf8
READS SQL DATA
DETERMINISTIC
RETURN
(WITH RECURSIVE acct_names AS (
SELECT id, Super, Name, Name AS Path FROM sa_accounts WHERE ID = a
UNION ALL
SELECT
sup.ID,
sup.Super,
sup.Name,
CONCAT(sup.Name, ', ', acct_names.Path)
FROM acct_names
LEFT JOIN sa_accounts sup ON acct_names.Super = sup.ID
WHERE sup.ID IS NOT NULL
)
SELECT Path FROM acct_names WHERE `Super` IS NULL);
现在,示例数据将导致:
Account Super Name Debits Credits Net 1000000 null Assets -6.31 10.1 3.79 1010000 1000000 Assets, Cash -6.31 10.1 3.79 1010011 1010000 Assets, Cash, Chequing -5.3 0 -5.3 1019999 1010000 Assets, Cash, Test bank account -1.01 10.1 9.09 4000000 null Income -10.1 0 -10.1 4050000 4000000 Income, Dairy income -10.1 0 -10.1 4059999 4050000 Income, Dairy income, Test income source -10.1 0 -10.1 5000000 null Expenses 0 6.31 6.31 5050002 5000000 Expenses, Feed bought 0 5.3 5.3 5059999 5000000 Expenses, Test expense dest 0 1.01 1.01
(如果这个答案不合适,我深表歉意。我在评论部分没有看到 post 格式化代码的任何方法。)