SQL - 按唯一 ID 分组的 2 个条目之间的时间差
SQL - Time difference between 2 entries grouped by unique ID
我有一个 table,其中包含针对不同 ID 的不同操作的多个时间戳条目(我们称它们为操作 'A' 和 'B'),我想计算它们之间的差异每个 ID 在元数据库中使用 SQL。
为了让事情变得更复杂,我需要只过滤包含两种动作类型的ID,有时会有重复的动作名称并不总是相同的顺序,所以我需要找到动作的MIN 'A' 并希望获得 Action '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' 的 ID(提示:如果存在操作 'A',将始终有一个操作'B',但有时只有一个动作 'B'),并找到与第一个动作 'A'(在最早的动作 'B' 之后出现)的时间戳差异,以及下一个最高操作 'B'.
想要的结果:
ID | Difference
-----------------
01 | 5 min
10 | 10 min
总结一下:
• 我如何识别操作 'B' 后操作 'A' 的第一个时间戳?
• 如何计算该操作 'A' 与下一个最高操作 'B' 的差异,以便在每个不同 ID 的结果中显示在同一行中?
• 如何仅查看同时存在这两种操作的 ID?
我不知道你用的是哪种 SQL 方言,所以我试着写了一个非常接近标准 SQL 的查询(例如 SQL:2003), but using Postgres 8.4. For the character representation of date values, I used the format defined in 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 在线测试。
我有一个 table,其中包含针对不同 ID 的不同操作的多个时间戳条目(我们称它们为操作 'A' 和 'B'),我想计算它们之间的差异每个 ID 在元数据库中使用 SQL。
为了让事情变得更复杂,我需要只过滤包含两种动作类型的ID,有时会有重复的动作名称并不总是相同的顺序,所以我需要找到动作的MIN 'A' 并希望获得 Action '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' 的 ID(提示:如果存在操作 'A',将始终有一个操作'B',但有时只有一个动作 'B'),并找到与第一个动作 'A'(在最早的动作 'B' 之后出现)的时间戳差异,以及下一个最高操作 'B'.
想要的结果:
ID | Difference
-----------------
01 | 5 min
10 | 10 min
总结一下:
• 我如何识别操作 'B' 后操作 'A' 的第一个时间戳?
• 如何计算该操作 'A' 与下一个最高操作 'B' 的差异,以便在每个不同 ID 的结果中显示在同一行中?
• 如何仅查看同时存在这两种操作的 ID?
我不知道你用的是哪种 SQL 方言,所以我试着写了一个非常接近标准 SQL 的查询(例如 SQL:2003), but using Postgres 8.4. For the character representation of date values, I used the format defined in 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 在线测试。