SQL - выберите ненулевое значение на основе самой последней даты - PullRequest
0 голосов
/ 24 октября 2018

Я использую запрос SQL, чтобы получить самые последние ненулевые значения, кроме случаев, когда все пустые. Это основано на столбце 'id'.

Рассмотрим эту таблицу:

create table calc
(
     id int, 
     tms date,
     col1 int, 
     col2 int, 
     col3 int
);

insert into calc 
values (1, '1/1/2000', 100, 333, null),
       (1, '3/3/2000', null, 222, null),
       (1, '2/2/2000', 300, 111, null);

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

1,'3/3/2000',300,222,null

Ниже приведен запрос, который я выполнил, но он возвращает только строку с максимальной датой

select 
    c.id, max_dt, col1, col2, col3
from 
    calc c
inner join 
    (select id, max(tms) as max_Dt
     from calc
     group by id) a on a.id = c.id and a.max_dt = tms;

Фактический результат:

1,'3/3/2000',null,222,null

Любойидеи о том, как получить желаемое решение?

Ответы [ 4 ]

0 голосов
/ 25 октября 2018

Вы можете сделать это вообще без подзапросов, используя ключевое слово keep:

select id, max(tms),
       max(col1) keep (dense_rank first order by (case when col1 is not null then 1 else 2 end), tms desc) as col1,
       max(col2) keep (dense_rank first order by (case when col2 is not null then 1 else 2 end), tms desc) as col2,
       max(col3) keep (dense_rank first order by (case when col3 is not null then 1 else 2 end), tms desc) as col3
from calc
group by id;

Здесь - это db <> скрипка.

0 голосов
/ 24 октября 2018
  SELECT t11.id,
           t14.tms,
           t11.col1,
           t12.col2,
           t13.col3
    FROM
      (SELECT calc.id,
              col1
       FROM calc
       INNER JOIN
         (SELECT id,
                 max(tms) tms
          FROM calc
          WHERE col1 IS NOT NULL
          GROUP BY id)AS t1 ON t1.id = calc.id
       AND t1.tms = calc.tms) AS t11
    LEFT JOIN
      (SELECT calc.id,
              col2
       FROM calc
       INNER JOIN
         (SELECT id,
                 max(tms) tms
          FROM calc
          WHERE col2 IS NOT NULL
          GROUP BY id)AS t2 ON t2.id = calc.id
       AND t2.tms = calc.tms) AS t12 ON t11.id = t12.id
    LEFT JOIN
      (SELECT calc.id,
              col3
       FROM calc
       INNER JOIN
         (SELECT id,
                 max(tms) tms
          FROM calc
          WHERE col3 IS NOT NULL
          GROUP BY id)AS t3 ON t3.id = calc.id
       AND t3.tms = calc.tms) AS t13 ON t11.id = t13.id
    INNER JOIN
      (SELECT id,
              max(tms) tms
       FROM calc
       GROUP BY id)AS t14 ON t11.id = t14.id
0 голосов
/ 24 октября 2018

Я сделал несколько модификаций вашего исходного запроса.Как вы написали, это нормально, чтобы иметь нулевое значение в третьей позиции в вашем выводе, показанном выше, это выглядит так:

select * from calc where id =1 and tms = '3/3/2000');

Можете ли вы попробовать это:

select c.id, nvl(tms,max_dt) tms, nvl(col1,mcol1) col1, nvl(col2,mcol2) col2, 
nvl(col3,mcol3) col3
from 
calc c
inner join 
(select id, max(tms) max_Dt, max(col1) mcol1, max(col2) mcol2, max(col3) mcol3 
 from calc
 group by id) a on a.id = c.id and a.max_dt = tms;

Надеюсь, что это можетпомочь вам.

0 голосов
/ 24 октября 2018

Вот общий способ SQL сделать это («трудный путь»).Возможно, это можно улучшить, если вы предоставите СУБД, которую вы используете.

select id,
    max(tms) as max_dt,
    (select col1 
        from calc c1 
        where c1.id = c.id and c1.tms = 
        (select max(tms) from calc where id = c1.id and col1 is not null) ) max_col1,
    (select col2 
        from calc c2 
        where c2.id = c.id and c2.tms = 
        (select max(tms) from calc where id = c2.id and col2 is not null) ) max_col2,
    (select col3 
        from calc c3 
        where c3.id = c.id and c3.tms = 
        (select max(tms) from calc where id = c3.id and col3 is not null) ) max_col3
from calc c
group by id;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...