2016-11-22 4 views
1

Столбец «amount» имеет значение 5 в первой строке и значение -10 во второй строке.Предотвращение общего числа от отрицательных в Oracle

Есть ли способ сделать функцию oracle over() для возврата 0 вместо -5 для второй строки?

+0

использовать случай заявление. 'case when windowfunction <0 then 0 else windowfunction завершает как Amount' или делает CTE и выбирает из cte и ahve оператор case вычисляет сумму. – xQbert

+0

Но я хочу, чтобы 0 отражалось в следующих строках (3, 4-й и т. Д.). Дело не поможет мне с этим. – Marko

+0

@Marko - Вот почему полезно разместить некоторые примеры данных, которые объясняют ваши примеры –

ответ

2

Грубо, используя пример источника Раджеша Chamarthi в: но изменения, чтобы показать более негативные и позитивные ... и показывая, как случай изменит все отрицательное к нулю, сохраняя при этом другие суммы ...

with t as (
    select 5 as x, 1 as id from dual 
    union all 
    select -10, 2 as id from dual 
    union all 
    select 7, 3 as id from dual 
    union all 
    select -5, 4 as id from dual 
    union all 
    select -2, 5 as id from dual 
), 
B as (select t.x, 
     case when sum(x) over (order by id) < 0 then 0 
       else sum(x) over (order by id) 
     end Amount 
from t 
order by id) 
Select X, Case when amount < 0 then 0 else amount end as Amount from B; 

    T Amount 
    5  5 
-10  0 
    7  2 
-5  0 
-2  0 

---- попытка 2 (1-я попытка сохранившийся в виде комментариев ниже ссылку на него)

Я не мог понять, как прервать функцию окна, чтобы сбросить значение до 0, когда количество упало ниже 0 ... поэтому я использовал рекурсивный CTE, который дал мне больший контроль.

Если идентификаторы не являются последовательными, мы могли бы добавить row_Number, чтобы у нас был идентификатор для присоединения ... или мы могли бы использовать min() где> oldID. Я предположил, что мы имеем один ключ уникальный идентификатор или каким-то образом «Сортировка» записей в порядке, вы хотите, чтобы произойти сумма ...

with aRaw as (
    select 5 as x, 15 as id from dual 
    union all 
    select -10, 20 as id from dual 
    union all 
    select 7, 32 as id from dual 
    union all 
    select 2, 46 as id from dual 
    union all 
    select -15, 55 as id from dual 
    union all 
    select 3, 68 as id from dual 
), 
t as (Select A.*, Row_number() over (order by ID) rn from aRAW A), 

CTE(RN, ID, x, SumX) AS (
Select T.RN, T.ID, x, X from t WHERE ID = (Select min(ID) from t) 
UNION ALL 
Select T.RN, T.ID, T.X, case when T.X+CTE.SumX < 0 then 0 else T.X+Cte.sumX end from T 
INNER JOIN CTE 
on CTE.RN+1=T.RN) 

Select * from cte; 

.

  1. КТР: Araw просто установить выборки данных
  2. КТР: Т добавляет Sequental номер строки упаковывают существуют пробелы в идентификаторы, позволяющие для более простого подхода, соединяющего на рекурсивной КТР.
  3. КТР: КТР рекурсивное CTE, что держит нарастающим итогом и имеет тематическое заявление, чтобы сбросить текущее общее значение 0, когда она падает ниже 0
+0

Я хочу видеть 7 вместо 2 в правом столбце – Marko

+0

Итак, вы хотите перезапустить нумерацию при достижении 0; понял. – xQbert

+0

Thats right .... – Marko

1

Вы можете использовать случай заявление, но это не был бы истинным нарастающим итогом

with t as (
    select 5 as x, 1 as id from dual 
    union all 
    select -10, 2 as id from dual 
    union all 
    select 20, 3 as id from dual 
    union all 
    select 30, 4 as id from dual 
    union all 
    select 10, 5 as id from dual 
) 
select t.x, 
     case when sum(x) over (order by id) < 0 then 0 
       else sum(x) over (order by id) 
     end running_total 
from t 
order by id; 

X RUNNING_TOTAL 

5 5 
-10 0 
20 15 
30 45 
10 55