¿Es posible escribir una consulta SQL que pueda resolverse de forma automática / pagos y cargas “transactionalizes”

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

  •  16-10-2019
  •  | 
  •  

Pregunta

Todavía estoy trabajando en el proyecto mencionado aquí (http://dba.stackexchange.com/questions/2428/how-do-i-properly-design-a-many-to-many-charges-payments- contabilidad del sistema).

El sistema es dar al usuario la opción de cantidades específicas de pago de los cargos específicos, o hacer genérico "a averiguarlo" pagos. Dada la estructura de la tabla fuimos con (pagos, cargos, PAYMENTS_TO_CHARGES) Estoy Buscando a engañar un poco. Básicamente estoy buscando un llamativo "reconciliar" consulta SQL sorprendentemente que hacer lo siguiente:

PASO 1) Cuchara de todos los pagos con saldo restante (básicamente créditos)

PASO 2) Cuchara de todos los Cargos con saldo restante (parcialmente pagadas, etc)

PASO 3) porciones de inserción de los pagos en la tabla PAYMENTS_TO_CHARGES hasta que no haya más crédito disponible o no hay más cargos.

... supongo que técnicamente esto no es la reconciliación tanto como la creación de datos de transacciones, pero se entiende la idea.

los pasos 1 y 2 son, evidentemente, muy fácil. Es el paso 3 que es el asesino. Si no hay manera elegante de hacer esto en SQL, supongo que iré con el antiguo código manual paso a paso en bucle-payment_to_charge cada transacción y después ... sólo pensé en preguntar.

Gracias de antemano!

EDIT 1: Yo he llegado con esta consulta para determinar qué cargos han saldo restante, pero me da un error que dice "Desconocido columna 'remaining_balance' en 'cláusula 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()

estoy seguro de ciertos artículos son simplemente fuera de servicio, pero no puedo averiguar lo que es generalmente mal con esta consulta en particular. ¿Debo utilizar en lugar de HAVING DONDE? Me estoy perdiendo algo completamente obvio?

¿Fue útil?

Solución

podría ser capaz de hacer el INSERT en Payemnts_To_Charges en una sentencia SQL, pero no estoy seguro de que sería la pena. Parece que esto sería más fácil de construir, depurar y mantener en el código de procedimiento. Algo como esto:

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;

Actualización:

remaining_balance es la cuestión. No se puede hacer referencia al valor de alias en la cláusula WHERE. Usted podría hacer la consulta de un sub-consulta y añadir esa condición en un nivel más alto o el cambio remaining_balance en la cláusula WHERE para. (Charges.amount - transactions.total_paid)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a dba.stackexchange
scroll top