Получить сумму по значению столбца, которое определяется двумя другими значениями столбца в той же таблице - PullRequest
0 голосов
/ 28 января 2019

У меня есть следующая таблица MY_TABLE

ID | SEQ | TYPE | VAL
1  | 2   | A    | 100
1  | 3   | A    | 100
1  | 2   | B    | 200
1  | 3   | A    | 100
1  | 3   | B    | 200
2  | 25  | X    | 100
2  | 24  | Y    | 200
2  | 24  | X    | 300
2  | 25  | Y    | 400
2  | 25  | X    | 50

Здесь, в MY_TABLE, каждый ID имеет набор значений Seq и Type.Я хочу получить сумму VAL строк на TYPE, которые принадлежат каждому ID s max(Seq).

Ожидаемый результат:

ID| SEQ | TYPE | SUM(VAL)
1 | 3   | A    | 200  <- 100 + 100
1 | 3   | B    | 200  
2 | 25  | X    | 150  <- 100 + 50
2 | 25  | Y    | 400

Что я пробовал:

-- this sub query finds the max(seq) for each ID
with max_seq as (
  select id, max(seq) max_seq
  from my_table t
  group by id)
-- select query on my_table
select
  bd.id,
  bd.seq,
  bd.type,
  sum(bd.val)
from my_table bd
-- joining on id-max_seq pair
inner join max_seq 
  on 
  (max_seq.id = bd.id)
  and
  (max_seq.max_seq = bd.seq)
-- sum(val) per ID, MAX(SEQ), TYPE
group by bd.id, bd.seq, bd.type;

Вопрос:

Приведенный выше запрос хорошо работает для небольших таблиц, но становится медленнее, когда таблица больше.Есть ли эффективный способ получить этот результат?(Может быть, без использования двух объединений в одной таблице с подзапросом?)

1 Ответ

0 голосов
/ 28 января 2019

Вы можете избежать самостоятельного объединения, используя подзапрос, который получает ранжирование для каждой строки на основе id и seq:

select id, seq, type, sum(val)
from (
  select id, seq, type, val, rank() over (partition by id order by seq desc) as rnk
  from my_table
)
where rnk = 1
group by id, seq, type
order by id, seq, type;

        ID        SEQ T   SUM(VAL)
---------- ---------- - ----------
         1          3 A        200
         1          3 B        200
         2         25 X        150
         2         25 Y        400

Из-за order by seq desc, rnk значение равно 1 для самого высокого seq для каждого id.Внешний запрос затем просто фильтрует по rnk = 1, ограничивая вывод и агрегацию этими строками самого низкого ранга (наивысшего seq).

db <> демо fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...