Можно ли написать SQL -запрос, который автоматически согласовывает/«транзакции» и платежи

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

  •  16-10-2019
  •  | 
  •  

Вопрос

Я все еще работаю над упомянутым здесь проектом (http://dba.stackexchange.com/questions/2428/how-do-i-properly-design-a-many-t-many-ghrages-payments-accounting-system )

Система должна дать пользователю возможность либо выплатить конкретные суммы на определенные сборы, либо сделать платежи «вы выясняете». Учитывая структуру таблицы, с которой мы пошли (платежи, платежи, платежи_TO_CHARGES), я хочу немного обмануть. По сути, я ищу удивительно шикарный «Приминный» SQL -запрос, который сделает следующее:

Шаг 1) Возьмите все платежи с оставшимся балансом (в основном кредиты)

Шаг 2) Возьмите все расходы с оставшимся балансом (частично оплачиваемая и т. Д.)

Шаг 3) Вставьте части платежей в таблице платежей_TO_CHARGES, пока не будет больше доступных кредитов или больше нет сборов.

... Я думаю, технически это не примирение настолько, как создание транзакционных данных, но вы понимаете.

Шаги 1 и 2, очевидно, очень просты. Это шаг 3, это убийца. Если в SQL нет шикарного способа сделать это, я полагаю, что я пойду со старой ручной кодированной пошаговой петлей и пост-транзакцией и после платежа_TO_CHAGHT ... просто подумал, что я спрошу.

Заранее спасибо!

РЕДАКТИРОВАТЬ 1:Я придумал этот запрос, чтобы определить, какие заряды имеют оставшийся баланс, но он дает мне ошибку, в которой говорится «неизвестный столбец», оставшиеся_балс 'в «где предложение»::

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()

Я уверен, что определенные предметы просто не в порядке, но я не могу понять, что вообще не так с этим конкретным запросом. Должен ли я использовать наличие вместо того, где? Я упускаю что -то еще совершенно очевидное?

Это было полезно?

Решение

Возможно, вы сможете сделать вставку в Payemnts_to_charges в одном операторе SQL, но я не уверен, что это того стоит. Кажется, что это будет проще построить, отлаживать и поддерживать в процедурном коде. Что-то вроде этого:

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;

Обновлять:

Остальное_балос - это проблема. Вы не можете ссылаться на псевдоним в пункте «Где. Вы можете либо сделать запрос подпроводом и добавить это условие на более высоком уровне, либо изменить оставшиеся_баловые в предложении «Где» (заряды.amount - transactions.total_paid).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с dba.stackexchange
scroll top