E 'possibile scrivere una query SQL che riconcilia automaticamente / pagamenti e oneri “transactionalizes”

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

  •  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?

È stato utile?

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)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a dba.stackexchange
scroll top