¿Es posible escribir una consulta SQL que pueda resolverse de forma automática / pagos y cargas “transactionalizes”
-
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?
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)