MsSQL遍历结果以检查并获取更多数据

时间:2018-07-03 13:00:33

标签: sql sql-server

我正在查询我们的事件表

SELECT id, user_id, date, time, event_type_id FROM events
WHERE date >= '2018-05-01'
AND event_type_id = 3

这将返回类似的内容

+------------+-------------+-------------------------+-------------------------+----------------+
| id         | user_id     |          date           |          time           | event_type_id  |
+------------+-------------+-------------------------+-------------------------+----------------+
|    5550579 |        1887 | 2018-05-03 00:00:00.000 | 2000-01-01 08:10:46.000 |              3 |
|    5550581 |        1887 | 2018-05-03 00:00:00.000 | 2000-01-01 08:41:38.000 |              3 |
|    5550629 |         993 | 2018-05-03 00:00:00.000 | 2000-01-01 08:01:59.000 |              3 |
|    5550662 |         546 | 2018-05-03 00:00:00.000 | 2000-01-01 09:13:04.000 |              3 |
|    5550711 |        1869 | 2018-05-03 00:00:00.000 | 2000-01-01 09:05:58.000 |              3 |
|    5550730 |        1148 | 2018-05-03 00:00:00.000 | 2000-01-01 09:15:20.000 |              3 |
|    5550732 |         611 | 2018-05-03 00:00:00.000 | 2000-01-01 09:26:26.000 |              3 |
|    5550733 |         627 | 2018-05-03 00:00:00.000 | 2000-01-01 09:26:32.000 |              3 |
|    5550734 |         530 | 2018-05-03 00:00:00.000 | 2000-01-01 09:27:32.000 |              3 |
|    5550767 |         566 | 2018-05-03 00:00:00.000 | 2000-01-01 09:50:15.000 |              3 |
|    5550810 |         415 | 2018-05-03 00:00:00.000 | 2000-01-01 10:10:01.000 |              3 |
|    5550812 |         556 | 2018-05-03 00:00:00.000 | 2000-01-01 10:14:08.000 |              3 |
|    5550878 |         777 | 2018-05-03 00:00:00.000 | 2000-01-01 10:39:19.000 |              3 |
|    5550896 |         926 | 2018-05-03 00:00:00.000 | 2000-01-01 09:45:22.000 |              3 |
|    5550900 |         926 | 2018-05-03 00:00:00.000 | 2000-01-01 10:06:25.000 |              3 |
|    5550901 |         780 | 2018-05-03 00:00:00.000 | 2000-01-01 10:06:29.000 |              3 |
|    5550902 |        1887 | 2018-05-03 00:00:00.000 | 2000-01-01 10:13:48.000 |              3 |
|    5550903 |        1938 | 2018-05-03 00:00:00.000 | 2000-01-01 10:16:35.000 |              3 |
|    5550915 |        2086 | 2018-05-03 00:00:00.000 | 2000-01-01 10:54:14.000 |              3 |
|    5550916 |        1796 | 2018-05-03 00:00:00.000 | 2000-01-01 10:54:15.000 |              3 |
+------------+-------------+-------------------------+-------------------------+----------------+

现在,我需要对结果的每一行进行迭代/查询,以检索特定用户在同一日期内下一次事件的时间,如下所示:

SELECT TOP 1 time FROM events
WHERE id > 5550579
AND user_id = 1887
AND date = '2018-05-03'

哪个返回:

+-------------------------+
|          time           |
+-------------------------+
| 2000-01-01 08:41:38.000 |
+-------------------------+

对于给定的结果,我应该比较第一次查询和第二次查询的时间。 2000-01-01 08:10:46.0002000-01-01 08:41:38.000

如果这两次的差值大于60分钟,则应保留第一个查询的结果,否则,应删除该行。最后,我应该具有从第一个查询开始的表列表,但仅具有该用户在两个事件之间的时间大于60分钟的结果。

我不知道这是否可以通过纯SQL或TSQL实现。我知道如何用某种编程语言而不是普通的SQL来做到这一点。

作为开发人员,我会做一些伪代码:

endresult = array()
query = select id, user_id, date, time, event_type_id from events where date >= '2018-05-01' and event_type_id = 3
foreach (query as row) {
    subquery = select top 1 time from events where id > row[id] and user_id = row[user_id] and date = row[date]
    if ((subquery[time] - row[time]) > 60) {
        endresult[] = row
    }
}

我用一些实际数据更新了这个问题。另外,因为我是开发人员而不是DBA专家,所以我也无法很好地解释它。

添加了示例数据,相应的列等用于测试目的

SQLFiddle链接-http://sqlfiddle.com/#!18/f83be

2 个答案:

答案 0 :(得分:1)

我喜欢乔治的回答,但他硬编码太多。这应该可以解决问题:

SELECT e1.id, e1.user_id, e1.date, e1.time, e1.event_type_id FROM events e1
WHERE e1.date >= '2018-05-01'
AND e1.event_type_id = 3
and dateadd(minute,60,e1.time)>
(
    SELECT TOP 1 e2.time FROM events e2
    WHERE e2.id > e1.id
    AND e2.user_id = e1.user_id
    AND e2.date = '2018-05-03'
    order by time desc
)

答案 1 :(得分:0)

这是您想要的吗?

SELECT id, user_id, date, time, event_type_id FROM events
WHERE date >= '2018-05-01'
AND event_type_id = 3
and dateadd(minute,60,time)>
(
    SELECT TOP 1 time FROM events
    WHERE id > 5550579
    AND user_id = 1887
    AND date = '2018-05-03'
    order by time desc
)

从您的伪代码中推断出,您只想要行(查询1),使得查询2的时间为60分钟更大(不是更小),对吗?

而且,正如肖恩·兰格(Sean Lange)正确评论的那样,您在第二个查询中的排序是什么?如果您需要同时将查询组合为有意义的,则意味着有意义。