Est-il possible d'écrire une requête SQL qui concilie automatiquement / paiements et charges « de transactionalizes »
-
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?
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)