SQL会计系统中的分级汇总

问题描述 投票:0回答:1

我正在尝试从会计系统中的一般日记帐分录制作年度报告(资产负债表和损益表。)>

普通日记帐表(简体)包括:

  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编号帐户方案中的“顶级”帐户:

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的帮助下,我可以使用以下代码进行use a Common Table Expression to sum up general journal entries by the difference of Source and Destination accounts

Source

到目前为止,太好了!这对我对如何使用通用表表达式的理解很有帮助!

但是现在,我想将子帐户“汇总”到抽象帐户中,从而获得类似于以下的预期结果:

Destination

[经过几次错误的开始之后,我想到了以下简单的想法,即在上面的代码周围简单地包裹一个WITH RECURSIVE,但是对具有相同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>
<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>

我知道最后一个SELECT有问题;正如我所说,这是我的第一次尝试,但我似乎遇到了无法克服的障碍。

执行前面的代码时,我收到“查询失败。对表'CTE2的递归定义施加了限制。错误代码4008。”经过大量的搜索,才能确定在此类查询的递归部分中不允许使用聚合查询(SUM等)。叹气。

我已经读过,有了RECURSIVE,SQL变得与Turing兼容,因此必须可以执行我要寻找的东西,但是在递归查询中没有SUM(),很难想象如何解决这个问题!] >

我正在尝试通过会计系统中的一般日记帐分录制作年度报告(资产负债表和损益表)。常规日记表(已简化)包括:CREATE TABLE`...

mysql common-table-expression finance recursive-datastructures accounting
1个回答
0
投票

此查询应为您提供所需的结果。它基于上一个问题的答案,并添加了一个递归CTE,该CTE可将每个交易复制到层次结构中位于其上方的所有帐户。然后,在最终查询中将每个帐户的值相加:

Super
© www.soinside.com 2019 - 2024. All rights reserved.