Запрос для получения суммы значений за максимальное количество месяцев - PullRequest
0 голосов
/ 08 ноября 2019

Этот запрос в Oracle 11 получает сумму значений за последние 1 год, и он работает, когда существует 1 год данных.

Когда данных меньше 1 года, этот запрос возвращает 0вместо суммы значений до того, какими бы ни были самые старые годы.

Например, если существует только 6 месяцев данных, запрос должен возвращать сумму значений до 6-го месяца.

SELECT SUM (DECODE (rnk, 11, rt, 0)) 1Y
FROM (SELECT entity_id,rnk,
             SUM (ABS(NVL (value, 0))) OVER (PARTITION BY TRIM (entity_id) ORDER BY rnk) rt
      FROM (SELECT psm.*,RANK () OVER (PARTITION BY entity_id ORDER BY period_end_date DESC) AS rnk
            FROM myTable psm
            WHERE psm.entity_id = '1'
            ORDER BY period_end_date DESC
           ) rank_tab
      WHERE rnk < 12
      );

Если наибольший ранг равен 6, результат вышеприведенного запроса будет 0

Я попытался это сделать, но получил ошибку «ORA-00978: функция вложенной группы без GROUP BY»

SELECT case when rnk < 11
                 then SUM (DECODE (rnk, Max(rnk), rt, 0))
            else SUM (DECODE (rnk, 11, rt, 0)) 
       end as Y
FROM (SELECT entity_id,rnk,
             SUM (ABS(NVL (value, 0))) OVER (PARTITION BY TRIM (entity_id) ORDER BY rnk) rt
      FROM (SELECT psm.*,RANK () OVER (PARTITION BY entity_id ORDER BY period_end_date DESC) AS rnk
            FROM myTable psm
            WHERE psm.entity_id = '1'
            ORDER BY period_end_date DESC
           ) rank_tab
      WHERE rnk < 12
     );

Пример данных:

entity_id   value   period_end_date 
1           1       9/30/19
1           2       8/31/19
1           3       7/31/19
1           4       6/30/19
1           5       5/31/19
1           6       4/30/19

В приведенном выше примере 1Y должен возвращать 1 + 2 + 3 + 4 + 5 + 6 = 21. Вместо этого мой запрос возвращает 0, поскольку он ищет rnk =11, который не существует.

SUM (DECODE (rnk, 11, rt, 0)) 1Y

Спасибо.

РЕДАКТИРОВАТЬ:

Это работает. Но, если вы знаете лучший способ сделать это, пожалуйста, дайте мне знать. Спасибо.

SELECT 
CASE WHEN MRank < 11 then maxY else OneY end as lc_incearned_1Y
FROM (
WITH R as
(SELECT MAX(RNK) MaxRank FROM (
SELECT RANK () OVER (PARTITION BY TRIM (entity_id) ORDER BY period_end_date 
DESC) AS rnk FROM myTbl psm
WHERE TRIM (psm.entity_id) = '1' AND period_end_date < 
to_date('9/30/2019','MM/DD/YYYY')
ORDER BY period_end_date DESC))
select MAX(MaxRank) MRank,
SUM (DECODE (rnk, MaxRank, rt, 0)) maxY,
SUM (DECODE (rnk, 11, rt, 0)) OneY,  --13051.97
FROM (SELECT entity_id,rnk,
SUM (ABS (NVL (value, 0))) OVER (PARTITION BY TRIM (entity_id) ORDER BY rnk) rt
FROM (SELECT psm.*,RANK () OVER (PARTITION BY TRIM (entity_id) ORDER BY period_end_date DESC) AS rnk FROM CREF.PORTFOLIO_SUMM_MTHEND psm
WHERE TRIM (psm.entity_id) = '1' AND period_end_date < to_date('9/30/2019','MM/DD/YYYY')
ORDER BY period_end_date DESC) rank_tab WHERE rnk < 12) T,R)

1 Ответ

0 голосов
/ 09 ноября 2019

Кажется, вам необходимо суммировать ваши значения начиная с самой последней даты period_end_date до самой ранней даты в пределах диапазона одиннадцати месяцев. Было бы целесообразно использовать аналитическую функцию max(period_end_date) over (partition by entity_id order by period_end_date desc) вместе с текущей функцией rank(). А затем применить months_between(<max_period_end_date>,period_end_date). Если вам нужно посмотреть текущую дату, избавьтесь от аналитической функции max() и замените <max_period_end_date> на trunc(sysdate) в функции months_between(). Итак, используйте:

with t as
(
select max(period_end_date) over (partition by entity_id order by period_end_date desc) as mx,
       rank() over (partition by entity_id order by period_end_date desc) as rnk,
       t.*
  from myTable t
)
select sum(nvl(value,0)) as sum_value
  from t
 where months_between(mx,period_end_date)<=11

Демо

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