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

У меня есть таблица:

ID | CMD_ID | VALUE | CREATED_TIMESTAMP
1       45   'test'   123456
2       46   'news'   123456
3       45   'test'   123457
4       46   'news'   123457
5       45   'TEST'   123468
6       46   'news'   123468

Я хочу получить каждый CMD_ID один раз и отметку времени последнего времени, когда значение этого CMD_ID было изменено.

Как мненаписать sql-запрос (для sqlite), который даст мне результат:

ID | CMD_ID | VALUE | CREATED_TIMESTAMP
2       46   'news'   123456
5       45   'TEST'   123468

?

Мое решение до сих пор:

select * from (select * from test as t where t.id 
in (select id from test group by value) order by id desc) group by 
cmd_id order by id;
enter code here

Это дает мне правильныйответьте, но есть ли более эффективный способ?

Ответы [ 4 ]

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

Вы должны быть очень осторожны.Допустим, у вас есть такие данные:

1    test
2    news
3    test

Если вы хотите получить значение от «1», то решения group by будут работать.Если вы хотите значение от «3», то проблема немного в другом.То, как сформулирован ваш вопрос, кажется, вам нужно «3».

Самые последние версии SQLite поддерживают оконные функции.Позвольте мне предположить, что вы используете более раннюю версию.

Следующий запрос идентифицирует конечную группу строк с тем же значением, присваивая значение 0 num_different_later:

select t.*,
       (select count(*)
        from t t2
        where t2.cmd_id = t.cmd_id and
              t2.created_timestamp > t.created_timestamp and
              t2.value <> t.value
       ) as num_different_after
from t;

Мы можем получить самую раннюю временную метку, используя агрегацию:

select cmd_id, value, min(created_timestamp)
from (select t.*,
             (select count(*)
              from t t2
              where t2.cmd_id = t.cmd_id and
                    t2.created_timestamp > t.created_timestamp and
                    t2.value <> t.value
             ) as num_different_after
      from t
     ) t
where num_different_later = 0;
0 голосов
/ 20 января 2019

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

select tablename.* from tablename 
inner join 
(select cmd_id, max(minstamp) as maxstamp from
  (select cmd_id, value, min(created_timestamp) as minstamp 
  from tablename 
  group by cmd_id, value)
group by cmd_id) as t
on t.cmd_id = tablename.cmd_id and t.maxstamp = tablename.created_timestamp

См. Демоверсию Редактировать После новых предоставленных вами дел я пришел к следующему:

select tablename.* from tablename inner join (
select t.cmd_id, max(t.created_timestamp) maxstamp from (
  select * from (
    select 
      t.*, (
        select value from tablename tt 
        where 
          tt.cmd_id = t.cmd_id 
          and 
          tt.created_timestamp = (
            select max(created_timestamp) from tablename 
            where 
              cmd_id = t.cmd_id 
              and
              created_timestamp < t.created_timestamp
          ) 
      ) previousvalue
    from tablename t   
  ) t  
  where 
    t.previousvalue is null 
    or 
    t.value <> t.previousvalue
  ) t
group by t.cmd_id
) t 
on t.cmd_id = tablename.cmd_id and t.maxstamp = tablename.created_timestamp

См. демо Попробуйте на этот раз исчерпывающе.

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

Для этого вы можете использовать оконную функцию row_number.Каждой записи будет присвоен порядковый номер, который она имеет в «разделе» (определяется как cmd_id).Если у вас есть этот номер в качестве дополнительной информации, вы можете отфильтровать записи, где этот номер равен 1:

select id, cmd_id, value, created_timestamp
from   (
          select test.*,
                 row_number() over (partition by cmd_id order by created_timestamp desc) rn
          from   test
       )
where  rn = 1
0 голосов
/ 20 января 2019

В sql sever вы можете получить максимальное значение из этих

SELECT id, max (timestamp) timestamp ИЗ таблицы GROUP BY id

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