Вычитание двух столбцов в группе по одной и той же таблице SQL - PullRequest
0 голосов
/ 27 августа 2018

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

create table events 
(
      event_type integer not null,
      value integer not null,
      time timestamp not null,
      unique(event_type, time)
);

Я хочу написать SQL-запрос, который для каждого, который был зарегистрирован более одного раза, возвращает разницу между самым последним (т.е. самым последним в терминах)и второй последний.Таблица должна быть упорядочена по (в порядке возрастания).

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

 event_type   | value      | time
 -------------+------------+--------------------
   2          |  5         | 2015-05-09 12:42:00
   4          | -42        | 2015-05-09 13:19:57
   2          |  2         | 2015-05-09 14:48:30
   2          |  7         | 2015-05-09 12:54:39
   3          | 16         | 2015-05-09 13:19:57
   3          | 20         | 2015-05-09 15:01:09

Выходные данные должны быть

   event_type | value
  ------------+-----------
   2          | -5
   3          | 4

Пока я пытался сделать это

SELECT event_type  
FROM events 
GROUP BY event_type
HAVING COUNT(event_type) > 1 
ORDER BY event_type

Я не могу найти способ два получить правильное значение для второго столбца, который я упомянул.Я использую PostgreSQL 9.4

Ответы [ 2 ]

0 голосов
/ 27 августа 2018

Один из способов сделать это, используя lead, который получает следующее значение данного столбца на основе указанного порядка. предпоследняя строка для данного event_type будет иметь самое последнее значение, которое в этом случае можно использовать для вычитания.(Запустите внутренний запрос, чтобы увидеть, как назначается next_val)

select event_type,next_val-value as diff
from (select t.*
      ,lead(value) over(partition by event_type order by time) as next_val, 
      ,row_number() over(partition by event_type order by time desc) as rnum
      from tbl t
     ) t 
where next_val is not null and rnum=2

Еще одна опция с DISTINCT ON и lead.

select distinct on (event_type) event_type,next_val-value as diff
from (select t.*,lead(value) over(partition by event_type order by time) as next_val 
      from events t
     ) t 
where next_val is not null 
order by event_type,time desc
0 голосов
/ 27 августа 2018

Вы можете сделать это, используя стандартные оконные функции ANSI / ISO:

select event_type,
       sum(case when seqnum = 1 then value
                when seqnum = 2 then - value
           end) as diff_latest
from (select e.*,
             row_number() over (partition by event_type order by time desc) as seqnum
      from events e
     ) e
where seqnum in (1, 2)
group by event_type
having count(*) = 2;

Здесь - это скрипта SQL.

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