Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将现金从一个账户推/拉至其他账户,并按账户跟踪余额_Sql_Postgresql - Fatal编程技术网

Sql 将现金从一个账户推/拉至其他账户,并按账户跟踪余额

Sql 将现金从一个账户推/拉至其他账户,并按账户跟踪余额,sql,postgresql,Sql,Postgresql,我正试图找出如何将现金从一个账户推/拉到其他账户,并按账户跟踪余额。我能想到的解释这一点的最佳模式是零用现金。有一个主要的零用现金账户,里面有现金,然后其他账户以先进先出的方式取出现金并放回现金。一旦所有交易都处理完毕,我想知道有多少零用现金被转移到了其他每个账户 规格 账户余额不应为负数;一旦零用现金用完,就不能再将其存入账户 交易将以先进先出的方式进行处理 负账户交易从零用现金账户中取出资金,正账户交易金额将资金放回 示例数据设置 预期产量 我终于想出了一个办法。使用两步流程,我首先计算每个

我正试图找出如何将现金从一个账户推/拉到其他账户,并按账户跟踪余额。我能想到的解释这一点的最佳模式是零用现金。有一个主要的零用现金账户,里面有现金,然后其他账户以先进先出的方式取出现金并放回现金。一旦所有交易都处理完毕,我想知道有多少零用现金被转移到了其他每个账户

规格

账户余额不应为负数;一旦零用现金用完,就不能再将其存入账户 交易将以先进先出的方式进行处理 负账户交易从零用现金账户中取出资金,正账户交易金额将资金放回 示例数据设置

预期产量


我终于想出了一个办法。使用两步流程,我首先计算每个账户交易的调整金额,通过同一账户的任何可用退款(FIFO)减少支出。然后,在步骤2中,我使用这些调整后的金额,FIFO从零用现金中提取

CREATE TABLE IF NOT EXISTS transactions (
   id serial PRIMARY KEY, account_id int, date DATE, amount int);

INSERT INTO transactions (account_id, date, amount) VALUES
 /* Petty cash account transaction; 
    all other accounts will pull from this cash */
 (1, '2017-01-01', 5),

 /* Other account transactions that will
    pull from petty cash */
 (2, '2017-01-02', -2),
 (3, '2017-01-03', -8),
 (4, '2017-01-04', -6),
 (3, '2017-01-05', 10),
 (2, '2017-01-06', 1);


WITH e_adjusted_amounts AS (
    SELECT id, account_id, amount,
        /* adjusted_amount: the amount adjusted for returns, FIFO.
       This gives us a logical amount for outflows, adjusted for corresponding inflows
       that can be used later when we start pulling from petty cash. */
        amount - LEAST(0, GREATEST(amount,
            -(  -- total of all preceeding outflows
                COALESCE((SUM(amount) FILTER (WHERE amount < 0) OVER (PARTITION BY account_id ORDER BY id)) - amount,0)
                -- total of all inflows
              + COALESCE(SUM(amount) FILTER (WHERE amount > 0) OVER (PARTITION BY account_id),0)

             )
            )
        ) as adjusted_amount
    FROM transactions
),
e_pull_amounts AS (
    SELECT a.id, a.account_id, a.amount, a.adjusted_amount, LEAST(0, GREATEST(a.adjusted_amount,
             -(  petty_cash.amount
                 -- total of all preceeding outflows
               + COALESCE((SUM(a.adjusted_amount) OVER (ORDER BY id)) - a.adjusted_amount,0)
             )
            )
        ) as pull_amount
    FROM e_adjusted_amounts a,
        (SELECT amount FROM transactions WHERE account_id = 1) petty_cash
    -- Outflows only
    WHERE adjusted_amount < 0
    AND account_id != 1
)
SELECT account_id, SUM(pull_amount) as cash_balance
FROM e_pull_amounts
GROUP BY account_id
ORDER BY account_id;
| account_id | cash_balance | notes                                              | 
|------------|--------------|----------------------------------------------------| 
| 1          | 0            | Petty cash account depleted                        | 
| 2          | 1            | Total spending was -1                              | 
| 3          | 0            | Total spending was +2, we gave all petty cash back | 
| 4          | 4            | Total spending was -6, we had 4 left to pull       | 
CREATE TABLE IF NOT EXISTS transactions (
   id serial PRIMARY KEY, account_id int, date DATE, amount int);

INSERT INTO transactions (account_id, date, amount) VALUES
 /* Petty cash account transaction; 
    all other accounts will pull from this cash */
 (1, '2017-01-01', 5),

 /* Other account transactions that will
    pull from petty cash */
 (2, '2017-01-02', -2),
 (3, '2017-01-03', -8),
 (4, '2017-01-04', -6),
 (3, '2017-01-05', 10),
 (2, '2017-01-06', 1);


WITH e_adjusted_amounts AS (
    SELECT id, account_id, amount,
        /* adjusted_amount: the amount adjusted for returns, FIFO.
       This gives us a logical amount for outflows, adjusted for corresponding inflows
       that can be used later when we start pulling from petty cash. */
        amount - LEAST(0, GREATEST(amount,
            -(  -- total of all preceeding outflows
                COALESCE((SUM(amount) FILTER (WHERE amount < 0) OVER (PARTITION BY account_id ORDER BY id)) - amount,0)
                -- total of all inflows
              + COALESCE(SUM(amount) FILTER (WHERE amount > 0) OVER (PARTITION BY account_id),0)

             )
            )
        ) as adjusted_amount
    FROM transactions
),
e_pull_amounts AS (
    SELECT a.id, a.account_id, a.amount, a.adjusted_amount, LEAST(0, GREATEST(a.adjusted_amount,
             -(  petty_cash.amount
                 -- total of all preceeding outflows
               + COALESCE((SUM(a.adjusted_amount) OVER (ORDER BY id)) - a.adjusted_amount,0)
             )
            )
        ) as pull_amount
    FROM e_adjusted_amounts a,
        (SELECT amount FROM transactions WHERE account_id = 1) petty_cash
    -- Outflows only
    WHERE adjusted_amount < 0
    AND account_id != 1
)
SELECT account_id, SUM(pull_amount) as cash_balance
FROM e_pull_amounts
GROUP BY account_id
ORDER BY account_id;