sql >> データベース >  >> RDS >> Mysql

バランス修正を実行するためのMySqlクエリ

    先読みと読み返しが必要なため、セットベースのコードを使用してこれを行うことはできないと思います。何か手続きがうまくいく可能性があります。カーソルと一時テーブルを使用して、それをほぼ達成できます(累積バランスがマイナスにならないように、何かを追加する必要があります)。あなたが言うことから、最初の取引は決して残高をマイナスにすることはできませんが、私はそれをチェックします。クレジットプールからのテイクは、テイクが補償している借方よりも後の日付から来る可能性があることに注意してください-残高がマイナスになることは決してないので、それは問題ではないはずです(原文のまま)そしてもちろん、私はパフォーマンスを期待していません素晴らしいことです。

    DROP TABLE IF EXISTS T;
    create table t
    (trx_no int, trx_date date,    Opening int,debit int,  credit int);
    insert into t values
    (1    ,   '2019-10-01' , 200  ,   0     ,  100),    
    (2    ,   '2019-10-02' , 200  ,   0     ,  100),    
    (3    ,   '2019-10-03' , 200  ,   100   ,  0  ),     
    (4    ,   '2019-10-03' , 200  ,   400   ,  0  ),    
    (5    ,   '2019-10-03' , 200  ,   0     ,  200),      
    (6    ,   '2019-10-04' , 200  ,   0     ,  100),      
    (7    ,   '2019-10-05' , 200  ,   100   ,  0  ),
    (8    ,   '2019-10-05' , 200  ,   0     ,  400);
    
    DROP TABLE IF EXISTS stmT;
    create table stmt
    (trx_no int, trx_date date,    Opening int,debit int,  credit int, cumbal int);
    
    
    
    
    drop procedure if exists p;
    delimiter $$
    create procedure p()
    begin
    
     declare v_trx_no int;
     declare v_dt date;
     declare v_debit int;
     declare v_credit int;
    
     declare h_trx_no int;
     declare h_dt date;
     declare h_credit int;
    
     declare opbal int;
     declare rbal  int;
     declare done int default 0;
     declare cur cursor for select trx_no,trx_date,debit,credit from t order by trx_date,trx_no;
     DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    
     select opening into opbal from t order by trx_no limit 1;
     set rbal = opbal;
     drop table if exists creditpool;
     create temporary table if not exists creditpool as select trx_no,trx_date,credit,0 as used from t where  credit > 0; 
     #select * from creditpool;
        open cur;
        cursorloop:loop
            fetch cur into v_trx_no,v_dt,v_debit,v_credit;
             if done = true then  
            leave cursorloop;
             end if;  
             if v_credit > 0 and exists (select 1 from creditpool where trx_no = v_trx_no and used = 0) then 
                 if v_credit > 0 then
                     insert into stmt values (v_trx_no,v_dt,opbal,v_debit,v_credit, rbal + v_credit);
                     set rbal = rbal + v_credit;
                     update creditpool set used = 1 where trx_no = v_trx_no; 
                end if;
             end if;
             if v_debit > 0 and v_debit <= rbal then
                 insert into stmt values (v_trx_no,v_dt,opbal,v_debit,v_credit, rbal - v_debit);
                 set rbal = rbal - v_debit;
             elseif v_debit > 0 and v_debit > rbal then
                 poolloop: loop
                            select trx_no,trx_date,credit
                                into h_trx_no,h_dt,h_credit
                                from creditpool
                                where used = 0 
                                order by trx_date,trx_no limit 1;
                            insert into stmt values (h_trx_no,h_dt,opbal,0,h_credit, rbal + h_credit);
                            set rbal = rbal + h_credit;
                            update creditpool set used = 1 where trx_no = h_trx_no; 
    
                            if v_debit <= rbal then
                                insert into stmt values (v_trx_no,v_dt,opbal,v_debit,v_credit, rbal - v_debit);
                                set rbal = rbal - v_debit;
                                leave poolloop;
                            end if;
                 end loop poolloop;           
             end if;
        end loop cursorloop;
        close cur;
    end $$
    delimiter ;
    truncate stmt;
    call p();
    select * from stmt;
    
    +--------+------------+---------+-------+--------+--------+
    | trx_no | trx_date   | Opening | debit | credit | cumbal |
    +--------+------------+---------+-------+--------+--------+
    |      1 | 2019-10-01 |     200 |     0 |    100 |    300 |
    |      2 | 2019-10-02 |     200 |     0 |    100 |    400 |
    |      3 | 2019-10-03 |     200 |   100 |      0 |    300 |
    |      5 | 2019-10-03 |     200 |     0 |    200 |    500 |
    |      4 | 2019-10-03 |     200 |   400 |      0 |    100 |
    |      6 | 2019-10-04 |     200 |     0 |    100 |    200 |
    |      7 | 2019-10-05 |     200 |   100 |      0 |    100 |
    |      8 | 2019-10-05 |     200 |     0 |    400 |    500 |
    +--------+------------+---------+-------+--------+--------+
    8 rows in set (0.00 sec)
    

    テイクは必要な場合にのみ発生するため、結果は目的の結果とわずかに異なることに注意してください。




    1. Sonar MySQLデータベースにアクセスできません原因:java.sql.SQLException:ユーザー'sonar' @'glassfishdev.ccs.local'のアクセスが拒否されました(パスワードを使用:YES)

    2. 日付ベースのレコードを15分間隔にグループ化する方法

    3. mysqlでSTOREDPROCEDUREを呼び出すと、なぜpdo-> lastInsertId()が0を返すのですか?

    4. 一時停止したときにサービスからアクティビティデータを更新する