支払いと料金を自動的に調整/「トランザクション化」するSQLクエリを作成することは可能ですか

dba.stackexchange https://dba.stackexchange.com/questions/3415

  •  16-10-2019
  •  | 
  •  

質問

私はまだここで言及されているプロジェクトに取り組んでいます(http://dba.stackexchange.com/questions/2428/how-i-properly-design-a-many-to-many-charges-payments-accountingsystem )。

このシステムは、特定の料金で特定の金額を支払うか、一般的な「あなたがそれを理解する」支払いをするか、ユーザーにオプションを提供することです。私たちが行ったテーブル構造を考えると(支払い、料金、支払い_TO_CHARGES)、私は少し不正行為をしたいと思っています。基本的に、私は次のことを行う驚くほどおしゃれな「reconcile」SQLクエリを探しています。

ステップ1)残りの残高(基本的にクレジット)ですべての支払いをつかむ

ステップ2)残りの残高(部分的に支払われるなど)ですべての料金をつかむ

ステップ3)利用可能なクレジットがなくなるか、料金がかからないまで、支払いの一部を支払い_TO_HARGESテーブルに挿入します。

…技術的には、これはトランザクションデータを作成するほど調和していないと思いますが、アイデアを得ることができます。

手順1と2は明らかに非常に簡単です。それはステップ3ですそれは殺人者です。 SQLでこれを行うおしゃれな方法がない場合は、古い手でコードされたステップバイステップループスルーエッチのトランザクションとPayune_To_Chargeを投稿してください。

前もって感謝します!

編集1:このクエリを思いついて、どの料金が残っているかを判断しましたが、「句の「reseming_balance」という不明な列「clause」」というエラーが発生しています。

SELECT 
       charges.*
     , (charges.amount - transactions.total_paid) as remaining_balance 
FROM charges
   , (SELECT 
             charge_id
           , sum(amount) as total_paid 
      FROM payments_to_charges 
      GROUP BY charge_id) as transactions 
WHERE charges.member_id = 123 
  AND charges.id = transactions.charge_id 
  AND remaining_balance > 0 
  AND charges.active_on < NOW()

特定のアイテムは単に故障していると確信していますが、この特定のクエリで一般的に何が悪いのかを理解することはできません。どこではなく持っている必要がありますか?私は他の何かが完全に明白なものを見逃していますか?

役に立ちましたか?

解決

1つのSQLステートメントでPayemnts_to_chargesに挿入を行うことができるかもしれませんが、それだけの価値があるかどうかはわかりません。これは、手続きコードで構築、デバッグ、および保守が簡単になるようです。このようなもの:

CREATE TABLE Payments (PaymentId Number(10), Amount Number(6,2));
CREATE TABLE Charges  (ChargeID Number(10), Amount Number(6,2));
CREATE TABLE Payments_To_Charges 
   (PaymentID Number(10), ChargeID Number(10), Amount Number(6,2));

INSERT INTO Payments VALUES (1,4);
INSERT INTO Payments VALUES (2,4);

INSERT INTO Charges VALUES (1,2);
INSERT INTO Charges VALUES (2,5);
INSERT INTO Charges VALUES (3,6);
INSERT INTO Charges VALUES (4,4);
INSERT INTO Charges VALUES (5,10);

Declare
   vPaymentAmount Payments.Amount%Type;
   vAppliedAmount Payments_To_Charges.Amount%Type;
Begin
   For vPayment In (SELECT PaymentID, Amount FROM Payments) Loop
      vPaymentAmount := vPayment.Amount;      
      For vCharge In (
            SELECT ChargeID, Amount FROM
            (
               SELECT ChargeID, Amount - 
                  NVL((SELECT SUM(Amount) FROM Payments_To_Charges pc 
                       WHERE pc.ChargeID = c.ChargeID),0) Amount
               FROM Charges c            
            ) WHERE Amount > 0
         ) Loop
         vAppliedAmount := LEAST(vPaymentAmount, vCharge.Amount);
         INSERT INTO Payments_To_Charges (PaymentID, ChargeID, Amount)
            VALUES (vPayment.PaymentID, vCharge.ChargeID, vAppliedAmount);
         vPaymentAmount := vPaymentAmount - vAppliedAmount;
         If (vPaymentAmount = 0) Then
            Exit;
         End If;
      End Loop;
   End Loop;
End;
/

SELECT * FROM Payments_To_Charges;

アップデート:

resight_balanceが問題です。 Where句のエイリアス値を参照することはできません。クエリをサブクエリにして、その条件をより高いレベルで追加するか、where句(Charges.amount -transactions.total_paid)のhwere句の変更を変更することができます。

ライセンス: CC-BY-SA帰属
所属していません dba.stackexchange
scroll top