Oracle
 sql >> Baza danych >  >> RDS >> Oracle

zapytanie dotyczące dystrybucji płatności Oracle sql

To dobry przypadek użycia dla MODEL SQL klauzula.

-- Set up test data (since I don't have your table)
with inv_raw (item_order, inv_amount, partial_pmt_allowed) as ( 
SELECT 1, 1256, 'N' FROM DUAL UNION ALL
SELECT 2, 1134, 'N' FROM DUAL UNION ALL
SELECT 3, 800, 'N' FROM DUAL UNION ALL
SELECT 4, 200, 'Y' FROM DUAL UNION ALL
SELECT 5, 156, 'Y' FROM DUAL),
-- Ensure that the column we are ordering by is densely populated
inv_dense (dense_item_order, item_order, inv_amount, partial_pmt_allowed) as 
( SELECT dense_rank() OVER ( PARTITION BY NULL ORDER BY item_order ), item_order, inv_amount, partial_pmt_allowed FROM inv_raw ),
-- Give us a way to input the payment amount
param as ( SELECT 1100 p_payment_amount FROM DUAL )
-- The actual query starts here
SELECT item_order,
 inv_amount,
 partial_pmt_allowed,
--remaining_in,
applied dist_amount,
remaining_out balance_amt
 FROM param, inv_dense
MODEL 
DIMENSION BY ( dense_item_order )
MEASURES ( p_payment_amount, item_order, inv_amount, partial_pmt_allowed, 0 applied, 0 remaining_in, 0 remaining_out )
RULES AUTOMATIC ORDER (
-- The amount carried into the first row is the payment amount
remaining_in[1] = p_payment_amount[1],
-- The amount carried into subsequent rows is the amount we carried out of the prior row
remaining_in[dense_item_order > 1] = remaining_out[CV()-1],
-- The amount applied depends on whether the amount remaining can cover the invoice 
-- and whether partial payments are allowed
applied[ANY] = CASE WHEN remaining_in[CV()] >= inv_amount[CV()] OR partial_pmt_allowed[CV()] = 'Y' THEN LEAST(inv_amount[CV()], remaining_in[CV()]) ELSE 0 END,
-- The amount we carry out is the amount we brought in minus what we applied
remaining_out[ANY] = remaining_in[CV()] - applied[CV()] 
)
ORDER BY item_order;

WYNIK

ITEM_ORDER |INV_AMOUNT |PARTIAL_PMT_ALLOWED |DIST_AMOUNT |BALANCE_AMT |
-----------|-----------|--------------------|------------|------------|
1          |1256       |N                   |0           |1100        |
2          |1134       |N                   |0           |1100        |
3          |800        |N                   |800         |300         |
4          |200        |Y                   |200         |100         |
5          |156        |Y                   |100         |0           |


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. zagnieżdżone wybierz lub dołącz do zapytania?

  2. Jak nazwać procedurę wyroczni na Laravelu?

  3. Wyzwalaj alternatywy dla dwóch tabel, które muszą się wzajemnie aktualizować

  4. Błąd Oracle SQL:brak parametru IN lub OUT w indeksie::1

  5. policz liczbę wierszy występujących dla każdej daty w zakresie dat kolumny