Выберите максимальные значения идентификатора из каждого столбца, где значения не равны NULL - PullRequest
0 голосов
/ 02 февраля 2020

Сценарий:

У меня есть таблица оценок. Каждый день импортируется новая запись, но иногда импорт не выполняется:

valuation_id  date         stock_A stock_B stock_C
1200          22/01/2020   17.6    22.4    10.5
1201          23/01/2020   18.2    26.1    10.2
1202          24/01/2020   15.5    26.8    10.8
1203          25/01/2020   12.5    28.2    NA
1204          26/01/2020   11.2    NA      NA
1205          27/01/2020   NA      NA      NA

Цель:

Мне нужно выбрать последнее доступное значение (цена) для каждого столбца (акции):

stock_A  stock_B  stock_C
11.2     28.2     10.8

Вопрос:

Как лучше всего выбрать MAX (valuation_id) для каждого столбца, в котором значение NOT NULL?

Ответы [ 4 ]

1 голос
/ 02 февраля 2020

Вы можете использовать следующее, используя подзапрос для получения максимального идентификатора на акцию и MAX с CASE для получения последних значений каждой акции:

SELECT MAX(CASE WHEN stock = 'A' THEN stock_A ELSE 0.0 END) AS stock_A,
  MAX(CASE WHEN stock = 'B' THEN stock_B ELSE 0.0 END) AS stock_B,
  MAX(CASE WHEN stock = 'C' THEN stock_C ELSE 0.0 END) AS stock_C
FROM transactions t INNER JOIN (
  SELECT MAX(valuation_id) AS max_valuation_id, 'A' AS stock FROM transactions WHERE stock_A IS NOT NULL
  UNION ALL
  SELECT MAX(valuation_id), 'B' FROM transactions WHERE stock_B IS NOT NULL
  UNION ALL
  SELECT MAX(valuation_id), 'C' FROM transactions WHERE stock_C IS NOT NULL
) mt ON mt.max_valuation_id = t.valuation_id

демо на dbfiddle.uk

1 голос
/ 02 февраля 2020

Вы можете использовать функцию LAST_VALUE() analyti c:

SELECT MAX(stock_A) AS stock_A, MAX(stock_B) AS stock_B, MAX(stock_C) AS stock_C 
  FROM
  (
   SELECT LAST_VALUE(stock_A IGNORE NULLS ) 
             OVER (ORDER BY valuation_id
                   ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS stock_A,
          LAST_VALUE(stock_B IGNORE NULLS ) 
             OVER (ORDER BY valuation_id
                   ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS stock_B,
          LAST_VALUE(stock_C IGNORE NULLS ) 
             OVER (ORDER BY valuation_id
                   ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS stock_C                   
     FROM tab 
  ) 

Демо

0 голосов
/ 03 февраля 2020

Вы можете использовать lag аналитическую функцию следующим образом:

Select stock_a, stock_b, stock_c
From
(Select Case when stock_a is null
            Then lag(stock_a ignore nulls) over (order by valuation_id) 
            else stock_a 
       end as stock_a,
       Case when stock_b is null
            Then lag(stock_b ignore nulls) over (order by valuation_id) 
            else stock_b
       end as stock_b,
       Case when stock_c is null
            Then lag(stock_c ignore nulls) over (order by valuation_id) 
            else stock_c 
       end as stock_c,
       Row_number() over (order by valuation_id desc) as rn
  From your_table)
Where rn = 1

Cheers !!

0 голосов
/ 02 февраля 2020

Еще один вариант:

SQL> with test (datum, stock_a, stock_b, stock_c) as
  2    (select date '2020-01-23', 18.2, 26.1, 10.2 from dual union all
  3     select date '2020-01-24', 15.5, 26.8, 10.8 from dual union all
  4     select date '2020-01-25', 12.5, 28.2, null from dual union all
  5     select date '2020-01-26', 11.2, null, null from dual
  6    )
  7  select distinct
  8    first_value(stock_a) over (order by datum desc) sa,
  9    first_value(stock_b) over (order by case when stock_b is null then date '0000-01-01' else datum end desc) sb,
 10    first_value(stock_c) over (order by case when stock_c is null then date '0000-01-01' else datum end desc) sc
 11  from test;

        SA         SB         SC
---------- ---------- ----------
      11,2       28,2       10,8

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