Найти разницу между группой полей, если значение группы 1 выше, чем значение группы 2 - PullRequest
1 голос
/ 15 апреля 2019

У меня есть таблица «Компоненты» со следующими полями

Person ID    Date_from      CompType       Value
000001       01/01/2003       A1            100
000001       01/01/2003       B1            200
000001       01/01/2003       C1            150
000001       01/01/2003       D1            180
000001       01/01/2003       E1            185
000001       01/01/2002       A1            125
000001       01/01/2002       B1            020
000001       01/01/2002       C1            130
000001       01/01/2002       D1            160
000001       01/01/2002       E1            105
000001       01/01/2001       A1            090
000001       01/01/2001       B1            200
000001       01/01/2001       C1            250
000001       01/01/2001       D1            160
000001       01/01/2001       E1            185

Мне нужно найти разницу между суммой (A1 + B1 + C1 + D1) как S1 и максимальной строки DATE_FROM (01/01/2003) и суммой (A1 + B1 + C1 + D1) как S2 для следующая дата, где S1-S2 <> 0

Аналогично, мне нужно найти разницу между суммой (A1 + B1 + C1 + D1) как S2 от предыдущих строк и суммой (A1 + B1 + C1 + D1) как S3 на следующую дату, где, S3- S2 <> 0

Итак, мой вывод будет

ID           Date        Current Difference   Previous Difference
000001       01/01/2003          195             245

Также, если я не найду никакой разницы в данных 01.01.2003 и 01.01.2002. SQL должен смотреть на разницу наборов данных 01.01.2003 и 01.01.2001.

Ответы [ 2 ]

0 голосов
/ 15 апреля 2019

Вы можете использовать lag() функцию с агрегацией и abs() в основном запросе как

with Components(Person_ID, Date_from, CompType, Value) as
(
 select '000001',date'2003-01-01','A1',100 from dual union all
 select '000001',date'2003-01-01','B1',200 from dual union all
 select '000001',date'2003-01-01','C1',150 from dual union all
 select '000001',date'2003-01-01','D1',180 from dual union all
 select '000001',date'2003-01-01','E1',185 from dual union all
 select '000001',date'2002-01-01','A1',125 from dual union all
 select '000001',date'2002-01-01','B1',20  from dual union all
 select '000001',date'2002-01-01','C1',130 from dual union all
 select '000001',date'2002-01-01','D1',160 from dual union all
 select '000001',date'2002-01-01','E1',105 from dual union all
 select '000001',date'2001-01-01','A1',90  from dual union all
 select '000001',date'2001-01-01','B1',200 from dual union all
 select '000001',date'2001-01-01','C1',250 from dual union all
 select '000001',date'2001-01-01','D1',160 from dual union all
 select '000001',date'2001-01-01','E1',185 from dual
), t2 as
(
select Person_ID, Date_from, sum(Value) as sum1, 
       lag(sum(Value),1,0) over (order by Date_from) as sum2,
       lag(sum(Value),2,0) over (order by Date_from) as sum3
  from Components
 where CompType != 'E1' 
 group by Person_ID, date_from
)
select Person_ID, date_from, 
       abs(sum1-sum2) as "Current Difference",
       abs(sum2-sum3) as "Previous Difference" 
  from t2
 where sum1 * sum2 * sum3 > 0;

PERSON_ID   DATE_FROM   Current Difference  Previous Difference
000001      01.01.2003        195                  265

Демо

0 голосов
/ 15 апреля 2019

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

select personId, date_from, 
       sum(case when comptype in ('A1', 'B1', 'C1', 'D1') then value end) as current_sum,
       lag(sum(case when comptype in ('A1', 'B1', 'C1', 'D1') then value end)) over (partition by personId order by min(date_from) as prev_sum,
       lag(sum(case when comptype in ('A1', 'B1', 'C1', 'D1') then value end), 2) over (partition by personId order by min(date_from) as prev_sum,
from t
group by personId, date_from
order by personId, date_from desc;

В Oracle 12C вы можете добавить fetch first 1 row only, чтобы получить верхнюю строку.

...