Est-il possible d'écrire une requête SQL qui concilie automatiquement / paiements et charges « de transactionalizes »

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

  •  16-10-2019
  •  | 
  •  

Question

Je travaille toujours sur le projet mentionné ici (http://dba.stackexchange.com/questions/2428/how-do-i-properly-design-a-many-to-many-charges-payments- comptabilité système).

Le système est de donner à l'utilisateur la possibilité soit de montants spécifiques de rémunération sur les frais spécifiques ou génériques faire « vous comprendre » paiements. Compte tenu de la structure de la table, nous sommes allés avec (paiements, frais, PAYMENTS_TO_CHARGES) Je suis à la recherche de tricher un peu. Fondamentalement, je suis à la recherche d'une tape à l'oeil étonnamment « réconcilier » requête SQL qui procédez comme suit:

ÉTAPE 1) Prenez tous les paiements avec solde (essentiellement des crédits)

ÉTAPE 2) Prenez tous les frais avec solde (paiement partiel, etc.)

ÉTAPE 3) Insérer des portions de paiements dans la table PAYMENTS_TO_CHARGES jusqu'à ce qu'il n'y a plus de crédit disponible ou il n'y a pas plus frais.

... Je suppose que techniquement ce n'est pas la réconciliation tant que la création de données transactionnelles, mais vous obtenez l'idée.

Les étapes 1 et 2 sont évidemment très facile. Il est l'étape 3 qui est le tueur. S'il n'y a pas tape à l'oeil façon de le faire dans SQL, je suppose que je vais à l'ancienne en boucle-chaque transaction, étape par étape codée à la main et payment_to_charge après ... juste pensé que je demande.

Merci à l'avance!

EDIT 1: Je suis venu avec cette requête afin de déterminer les charges ont restant l'équilibre, mais il me donne une erreur « Unknown column « remaining_balance » dans « where » »:

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()

Je suis sûr que certains éléments sont tout simplement hors d'usage, mais je ne peux pas comprendre ce qui est généralement le problème avec cette requête particulière. Devrais-je utiliser au lieu de PRESENTANT OÙ? Suis-je manque quelque chose d'autre tout à fait évident?

Était-ce utile?

La solution

Vous pourriez être en mesure de faire l'instruction INSERT INTO Payemnts_To_Charges dans une instruction SQL, mais je ne suis pas sûr que ce serait la peine. Il semble que ce serait plus facile à construire, déboguer et maintenir dans le code de procédure. Quelque chose comme ceci:

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;

Mise à jour:

remaining_balance est la question. Vous ne pouvez pas faire référence à la valeur crénelage dans la clause WHERE. Vous pouvez soit faire la requête d'une sous-requête et ajouter cette condition à un niveau supérieur ou changement remaining_balance dans la clause WHERE pour. (Charges.amount - transactions.total_paid)

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top