E 'possibile scrivere una query SQL che riconcilia automaticamente / pagamenti e oneri “transactionalizes”
-
16-10-2019 - |
Domanda
Sto ancora lavorando sul progetto menzionato qui (http://dba.stackexchange.com/questions/2428/how-do-i-properly-design-a-many-to-many-charges-payments- contabilità-system).
Il sistema è quello di dare all'utente l'opzione di importi specifici di paga con l'accusa specifici, o fare generico "a capirlo" pagamenti. Data la struttura della tabella siamo andati con (pagamenti, le spese, PAYMENTS_TO_CHARGES) Sto cercando di imbrogliare un po '. Fondamentalmente sto cercando un snazzy "conciliare" interrogazione incredibilmente SQL che farà il seguente:
FASE 1) Grab tutti i pagamenti con credito residuo (fondamentalmente crediti)
FASE 2) afferrare tutte Spese con saldo (in parte a pagamento, ecc)
FASE 3) Inserire le porzioni di pagamenti nella tabella PAYMENTS_TO_CHARGES fino a quando non c'è più credito disponibile o non ci sono altri costi.
... Credo che tecnicamente questo non è la riconciliazione tanto come la creazione di dati transazionali, ma si ottiene l'idea.
punti 1 e 2 sono ovviamente molto facile. E 'Fase 3 che è il killer. Se non c'è modo sgargianti per fare questo in SQL, suppongo che andrò con il vecchio codice a mano step-by-step loop-through-ogni transazione e payment_to_charge post ... solo pensato che avrei chiesto.
Grazie in anticipo!
Modifica 1: Mi è venuta in mente questa query per determinare quali accuse sono saldo, ma mi sta dando un errore che dice "Unknown column 'remaining_balance' in 'where 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()
Sono sicuro che alcune voci sono semplicemente fuori ordine, ma non riesco a capire cosa c'è di sbagliato in questo genere determinata query. Dovrei usare VISTA invece di Dove? Mi sto perdendo qualcosa di completamente ovvio?
Soluzione
Si potrebbe essere in grado di fare l'inserto nella Payemnts_To_Charges in un'istruzione SQL, ma non sono sicuro che sarebbe valsa la pena. Sembra che questo sarebbe più facile da costruire, il debug e mantenere in codice procedurale. Qualcosa di simile a questo:
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;
Aggiornamento:
remaining_balance è il problema. Non si può fare riferimento al valore alias nella clausola WHERE. Si potrebbe o rendere la query un sub-query e aggiungere tale condizione ad un livello più alto o il cambiamento remaining_balance nella clausola WHERE per. (Charges.amount - transactions.total_paid)