基本 SQL 复式记账分类账 - 如何拆分日记账分录

Jor*_*mov 5 sql postgresql accounting

使用此要点中的基本 SQL 模式:https://gist.github.com/NYKevin/9433376,如何创建拆分日记条目?

\n\n

我明白为什么entries表有一个单一金额,并带有指向要贷记/借记的帐户的指针 - 这迫使复式记账保持一致,并且可以轻松计算余额。

\n\n

但这似乎使得分割日记帐分录变得不可能。简单的例子是购买 \xc2\xa31200 时计算增值税:

\n\n
1. Credit "Creditors control" account with \xc2\xa31200\n2. Debit "VAT" account with \xc2\xa3200\n3. Debit "Purchases" account with \xc2\xa31000\n
Run Code Online (Sandbox Code Playgroud)\n\n

一个更复杂的例子是工资单,其中有一个借方是工资费用,另一个借方是工资税费用,贷方是现金和各种扣除账户。

\n\n

这个 SQL 模式是否不足以满足这些目的,或者是否有办法使用 Gist 中的 SQL 来实现此目的?

\n

小智 12

你是对的,你的要点中的示例模式使得不可能分割日记条目。

您需要的是一个每个单独的日记条目都有一行的模式。这是一种更灵活的设计,可以适应您正在寻找的复杂场景。

例子

模式

我建议至少三个表来满足您的要求:

CREATE TABLE account(
    account_id serial PRIMARY KEY,
    account_name text NOT NULL
);

CREATE TABLE financial_transaction (
    financial_transaction_id serial PRIMARY KEY,
    datetimestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    description text NOT NULL
);

CREATE TABLE journal(
    journal_id serial PRIMARY KEY,
    financial_transaction_id INTEGER REFERENCES financial_transaction(financial_transaction_id),
    account_id INTEGER REFERENCES account(account_id),
    amount NUMERIC(20, 2) NOT NULL,
    is_credit boolean NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

账户设置

我们将为您的示例创建三个帐户。尽管您可能不会对 进行硬编码id,但我们在这里这样做是为了演示

INSERT INTO account (account_id, account_name) VALUES (1, 'Creditors control');
INSERT INTO account (account_id, account_name) VALUES (2, 'VAT');
INSERT INTO account (account_id, account_name) VALUES (3, 'Purchases');
Run Code Online (Sandbox Code Playgroud)

购买交易示例

每笔财务交易只涉及插入表中的一行financial_transaction ,并且至少插入表中的两行journal,并且这些行的贷方和借方之和必须平衡。

INSERT INTO financial_transaction (financial_transaction_id, description)
VALUES (1, 'Purchase of widget');

INSERT INTO journal (financial_transaction_id, account_id, amount, is_credit)
VALUES (1, 1, 1200, TRUE);

INSERT INTO journal (financial_transaction_id, account_id, amount, is_credit)
VALUES (1, 2, 200, FALSE);

INSERT INTO journal (financial_transaction_id, account_id, amount, is_credit)
VALUES (1, 3, 1000, FALSE);
Run Code Online (Sandbox Code Playgroud)

笔记

您可以看到这种结构如何轻松容纳分体日记帐。该结构可以轻松查询,并且可以出于不同目的聚合交易或账户。

如果我要构建这个,我可能会创建一个触发器,以在任何交易结束时强制执行,其贷方和借方journal条目的总和达到平衡。我可能还想定义某些类型的交易以及可以为这些交易类型记录哪些类型的帐户,具体取决于我的系统的复杂程度或严格程度。

最后,我将创建规则、触发器或配置权限,以确保这些表中的行不会被删除或更新。在这样的系统中,所有更正都应通过附加交易进行。