Использование суммы и регистра в качестве цикла в Oracle работает правильно - PullRequest
0 голосов
/ 01 октября 2018

Я перебираю таблицу для вычисления IncomeTax , принимая налогооблагаемый в качестве параметра.Таким образом, цикл проходит через таблицу, вычисляет и суммирует значения.Я застрял там, где налогооблагаемая меньше совокупная сумма в отчете о сумме, тогда мы умножаем налогооблагаемый * процент . В этом примере объясняется нужная мне функция.Например

taxable=2000,
do 2000-261=1739 and do 0% * 261 = 0,
go to next line do 1739-70=1669 and do 5% * 70=3.5,
go to next line do 1669-100=1569 and do 10% *100.
go to next line,do 1569 < 2810, it should be 1569 *17.5%

multiply percentage by cummulative amount

CREATE OR REPLACE function CalculateIncomeTax2(taxableIncome NUMBER)
return NUMBER 
AS
IncomeTax NUMBER (10,2); 
BEGIN
SELECT 
 coalesce(SUM(     
  CASE WHEN (taxableIncome > T.TAX_CUMMULATIVE_AMOUNT) THEN ( 
(T.TAX_CUMMULATIVE_AMOUNT* T.TAX_PERCENTAGE)/ 100)                         
 ELSE 0.00 END
    ) ,0)                 
INTO IncomeTax
  FROM TAX_LAW T  

return IncomeTax
end; /

1 Ответ

0 голосов
/ 01 октября 2018

Итак, вы пишете функцию PL / SQL, но пытаетесь выполнить всю логику простым запросом SQL.Я думаю, что это, безусловно, возможно сделать с запросом SQL, но, поскольку ваша исходная логика структурирована как цикл, вам может быть проще использовать структуру цикла PL / SQL.

CREATE OR REPLACE function CalculateIncomeTax2(taxableIncome NUMBER)
return NUMBER 
AS
    IncomeTax NUMBER (10,2) := 0;
    TaxableRemainder NUMBER := taxableIncome;
BEGIN
    for r in (select tax_id, tax_percentage, tax_cummulative_amount
              from incometax
              order by tax_id)
    loop
        if TaxableRemainder > r.tax_cummulative_amount then
            TaxableRemainder := TaxableRemainder - r.tax_cummulative_amount;
            incometax := incometax + (r.tax_cummulative_amount * r.tax_percentage / 100);
        else
            incometax := incometax + (TaxableRemainder * r.tax_percentage / 100);
            exit; 
        end if;
    end loop;

    return IncomeTax;
end; 
/

Для вашего примераЯ получаю CalculateIncomeTax2(2000) = 288.08.Это немного отличается от того, что вы обычно получаете с калькулятором (288,075), потому что вы определили IncomeTax как NUMBER (10,2) с точностью до 2. Но, возможно, это то, что вы хотите?

Редактировать: Такв вашем SQL-запросе главное, чего вам не хватает, - это чтобы итоговая сумма суммы налога для каждой строки была необходима аналитическая / оконная функция .Вот пример того, как вы могли бы сделать то же самое вычисление в простом запросе SQL.(Вы можете значительно упростить этот запрос, но я думаю, что таким образом он более читабелен - вы можете легко посмотреть на подзапрос, чтобы увидеть, как создаются данные.)

select sum(tax_component)
from (
    select tax_id, tax_percentage, tax_cummulative_amount,
        taxableRemainder,
        case when taxableRemainder > tax_cummulative_amount 
            then (tax_cummulative_amount * tax_percentage / 100)
            else (taxableRemainder * tax_percentage / 100)
            end as tax_component
    from (
        select tax_id, tax_percentage, tax_cummulative_amount,
            nvl(2000-sum(tax_cummulative_amount) 
                     over (order by tax_id 
                        rows between unbounded preceding and 1 preceding),
                2000) 
                as taxableRemainder
        from incometax) it
)
;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...