SQL - разница во времени между двумя записями, сгруппированными по уникальному идентификатору - PullRequest
1 голос
/ 02 июля 2019

У меня есть таблица с несколькими записями временных отметок для разных действий (назовем их «А» и «В») для разных идентификаторов, и я хочу вычислить разницу между ними для каждого идентификатора, используя SQL в метабазе.

Чтобы усложнить задачу, мне нужно отфильтровать только идентификаторы, содержащие оба типа действий, и иногда встречаются повторяющиеся имена действий, которые не всегда находятся в одном и том же порядке, поэтому мне нужно найти МИНУЗ действий 'A'и хотел бы получить следующую наивысшую отметку времени действия' B '.

Например, вот набор данных:

ID   | Action | Timestamp
----------------------------------------------
01   | A      | Thursday, June 6, 2019 6:25 AM <-First valid action for 'A' for ID 01
01   | B      | Thursday, June 6, 2019 6:30 AM <-First valid action for 'B' for ID 01
01   | A      | Thursday, June 6, 2019 6:35 AM
01   | B      | Thursday, June 6, 2019 6:40 AM
01   | A      | Thursday, June 6, 2019 6:45 AM
03   | B      | Monday, July 1, 2019 8:25 AM   <-SKIP, due to no Action 'A' present for ID 03
03   | B      | Monday, July 1, 2019 8:30 AM
10   | B      | Tuesday, July 2, 2019 9:40 AM
10   | A      | Tuesday, July 2, 2019 9:45 AM  <-First valid action for 'A' for ID 10
10   | A      | Tuesday, July 2, 2019 9:50 AM
10   | B      | Tuesday, July 2, 2019 9:55 AM  <-First valid action for 'B' for ID 10

В результате я хотел бы просмотреть только идентификаторы, которыеиметь ОБА действие «А» и «В» (подсказка: если присутствует действие «А», всегда будет действие «В», но иногда есть только действие «В»), и найти разницу во временных меткахот первого действия «A» (которое происходит после самого раннего действия «B») и следующего наивысшего действия «B».

Желаемый результат:

ID   | Difference
-----------------
01   | 5 min
10   | 10 min

Итак, подведем итог:

• Какопределить первую временную метку действия «B» после действия «A»?

• Как рассчитать разницу от этого действия «A» и следующего наибольшего действия «B» для отображения в той же строкев результатах для каждого отдельного идентификатора?

• Как просмотреть только идентификаторы с обоими представленными действиями?

1 Ответ

1 голос
/ 03 июля 2019

Я не знаю, какой диалект SQL вы используете, поэтому я попытался написать запрос, очень близкий к стандартному SQL (например, SQL: 2003 ), но используя Postgres 8.4 .Для символьного представления значений даты я использовал формат, определенный в ISO 8601 .

create table T (
  ID char(2),
  Action char(1),
  "Timestamp" timestamp
);

insert into T values
  ('01', 'A', '2019-06-06T06:25'),
  ('01', 'B', '2019-06-06T06:30'),
  ('01', 'A', '2019-06-06T06:35'),
  ('01', 'B', '2019-06-06T06:40'),
  ('01', 'A', '2019-06-06T06:45'),
  ('03', 'B', '2019-07-01T08:25'),
  ('03', 'B', '2019-07-01T08:30'),
  ('10', 'B', '2019-07-02T09:40'),
  ('10', 'A', '2019-07-02T09:45'),
  ('10', 'A', '2019-07-02T09:50'),
  ('10', 'B', '2019-07-02T09:55');

select
  a.ID, extract(minute from (min(b."Timestamp") - a.min_ts)) as Difference
from (select
        t.ID, min(t."Timestamp") as min_ts
      from T as t
      where t.Action = 'A'
      group by t.ID, t.Action) as a
inner join T as b
  on a.ID = b.ID and b.Action = 'B' and a.min_ts < b."Timestamp"
group by a.ID, a.min_ts;

Вывод:

| id | difference |
+----+------------+
| 10 |         10 |
| 01 |          5 |

Тестэто онлайн с SQL Fiddle .

...