Создание настраиваемых записей в каждой группе записей в таблице с использованием SQL. На основе сценария - PullRequest
0 голосов
/ 07 мая 2020

Tab_X

**Col_1 Col_2   Col_3**
A1      B1      10
A1      B2      7
A2      B1      15
A2      B2      6

OUTPUT

**Col_1 Col_2   Col_3** 
A1      B1      10  
A1      B2      7   
**A1        null            3    {10 - 7}**
A2      B1      15  
A2      B2      6   
**A2        Null            9   {15 - 6}**

Все группы Col_1 должны иметь новую запись со значением col_3, как показано ниже = Col_3 {где col_2 = 'B1'} - СУММ (Col_3) {where col_2 <> 'B1'}

Кто-нибудь может предложить SQL для достижения этой цели?

Ответы [ 2 ]

1 голос
/ 07 мая 2020
with Tab_X (Col_1, Col_2, Col_3) as (
    select 'A1', 'B1', 10 from dual union all
    select 'A1', 'B2', 7  from dual union all
    select 'A2', 'B1', 15 from dual union all
    select 'A2', 'B2', 6  from dual
)
select *
from Tab_X
union all -- UPDATE, thanks @GordonLinoff
select Col_1
     , null
     , sum(Col_3 * case when Col_2 = 'B1' then 1 else -1 end)
from Tab_X
group by Col_1;

Комментарии:

  • пожалуйста, используйте CTE (с предложением) в вашей входной спецификации, чтобы сделать ответ более удобным
  • пожалуйста, отметьте вопрос поставщика БД. Из тега plsql, я думаю, у вас есть Oracle, в котором, к сожалению, нет предложения filter (where), поэтому обходной путь sum (case when)
  • может быть решен также с использованием group by rollup, но я не мог его придумать

ОБНОВЛЕНИЕ: решение на основе group by rollup

with Tab_X (Col_1, Col_2, Col_3) as (
    select 'A1', 'B1', 10 from dual union all
    select 'A1', 'B2', 7  from dual union all
    select 'A2', 'B1', 15 from dual union all
    select 'A2', 'B2', 6  from dual
)
select Col_1
     , null
     , case
         when grouping(Col_2) = 1 then sum(Col_3 * case when Col_2 = 'B1' then 1 else -1 end)
         else min(Col_3)
       end as Col_3
from Tab_X
group by Col_1, rollup (Col_2)
0 голосов
/ 07 мая 2020

Я использовал функцию задержки для значения col_3 предыдущей строки. А столбец «Ранг» для ловли меняет столбец col_1 (с А1 на А2). При его изменении ранг увеличивается.

with tab_x (col_1, col_2, col_3)
 as (select 'A1', 'B1', 10 from DUAL
     union
     select 'A1', 'B2', 7 from DUAL
     union
     select 'A2', 'B1', 15 from DUAL
     union
     select 'A2', 'B2', 6 from DUAL)  select x.col_1, x.col_2, x.col_3
from (select col_1,
             col_2,
             col_3,
             null RANK
        from (select col_1,
                     null col_2,
                     LAG (col_3, 1, 0) over (order by col_1) - col_3
                        as col_3,
                     null,
                     RANK ()
                        over (partition by col_1 order by col_1, col_2)
                        RANK
                from tab_x)
       where RANK = 2
      union all
      select col_1,
             col_2,
             col_3,               
             null RANK
        from tab_x
      order by col_1, col_2) x order by col_1, col_2
...