SQL 查询以特定顺序发生的事件
SQL Query for events that happend in a specific order
我有以下 table:
+--------+-------+------+--+
| Object | Event | Time | |
+--------+-------+------+--+
| Obj1 | A | 1 | |
| Obj1 | B | 3 | |
| Obj2 | A | 7 | |
| Obj2 | B | 4 | |
+--------+-------+------+--+
我的目标是获取同时具有事件 A 和 B 的所有对象,条件是 A 先发生(及时)。到目前为止,我只是想出查询来查找所有具有 A 和 B 的对象而不包括时间:
SELECT DISTINCT Object
FROM
(SELECT *
FROM
(SELECT *
FROM table
INNER JOIN
(SELECT Object Obj
FROM table
WHERE event LIKE '%A%' AS temp_table) ON table.Object = temp_table.Obj) AS temp_final
WHERE event LIKE '%B%') AS temp2;
所以最终结果是我得到一个 table,其中仅包含:
Obj1
因为这是唯一满足所有条件的对象。
时间栏是现实生活中的日期戳,但为简单起见,我使用了整数。
感谢您的帮助
这是一个紧凑的解决方案,应该 运行 跨大多数 RDBMS。此解决方案不假设只有两个事件,并且应该 运行 用于任意数量的事件。
SELECT t1.Object
FROM yourTable t1
INNER JOIN
(
SELECT Object, MIN(Time) AS Time
FROM yourTable
GROUP BY Object
) t2
ON t1.Object = t2.Object AND
((t1.Event = 'A' AND t1.Time = t2.Time) OR
t1.Event <> 'A')
GROUP BY t1.Object
HAVING COUNT(*) = 2 -- change this count to match # of events
MySQL 演示:
试试这个:
SELECT DISTINCT object
FROM yourtable t
WHERE EXISTS
(SELECT FROM yourtable t3
WHERE t3.object = t.object
AND t3.event = 'A'
AND EXISTS
(SELECT 'B'
FROM yourtbale t4
WHERE t4.object = t3.object
AND t4.event = 'B'
AND t4.time > t3.time)
)
如果您使用的是sql-服务器:
SELECT
A.[Object]
, A.[Time]
, B.[Time]
FROM
(SELECT
Distinct [Object]
FROM
[table] AS A
WHERE
A.[Event] = 'A'
) AS A
CROSS APPLY
(SELECT
TOP 1 *
FROM
[table] AS B
WHERE
[Event] = 'B'
AND
B.[Object] = A.[Object]
AND
A.[Time] < B.[Time]) AS B
如果您只跟踪一个接一个发生的两个事件,那么您可以用一个 JOIN
.
来解决这个问题
无论 Obj1
有多少事件,这都会起作用,正如你提到的,你只对 A
和 B
存在并且一个接一个地感兴趣,分别
select distinct t1.object
from TABLE t1
inner join TABLE t2 on t1.object = t2.object
and t2.time > t1.time
and t1.event = 'A'
and t2.event = 'B'
这是代码结果的示例:
declare @tbl table (obj varchar(10), event varchar(1), time int)
insert @tbl values ('Obj1', 'A', 1), ('Obj1', 'B', 3), ('Obj2', 'A', 7), ('Obj2', 'B', 4)
select distinct t1.obj
from @tbl t1
inner join @tbl t2 on t1.obj = t2.obj
and t2.time > t1.time
and t1.event = 'A'
and t2.event = 'B'
对于 SQL 服务器:
;with A as
(select Object, MIN(Time) as Time from table where Event='A' group by Object)
, B as
(select Object, MIN(Time) aS Time from table where Event='B' group by Object)
Select A.Object from A inner join B on B.Object=A.Object where A.Time < B.Time
我有以下 table:
+--------+-------+------+--+
| Object | Event | Time | |
+--------+-------+------+--+
| Obj1 | A | 1 | |
| Obj1 | B | 3 | |
| Obj2 | A | 7 | |
| Obj2 | B | 4 | |
+--------+-------+------+--+
我的目标是获取同时具有事件 A 和 B 的所有对象,条件是 A 先发生(及时)。到目前为止,我只是想出查询来查找所有具有 A 和 B 的对象而不包括时间:
SELECT DISTINCT Object
FROM
(SELECT *
FROM
(SELECT *
FROM table
INNER JOIN
(SELECT Object Obj
FROM table
WHERE event LIKE '%A%' AS temp_table) ON table.Object = temp_table.Obj) AS temp_final
WHERE event LIKE '%B%') AS temp2;
所以最终结果是我得到一个 table,其中仅包含:
Obj1
因为这是唯一满足所有条件的对象。
时间栏是现实生活中的日期戳,但为简单起见,我使用了整数。
感谢您的帮助
这是一个紧凑的解决方案,应该 运行 跨大多数 RDBMS。此解决方案不假设只有两个事件,并且应该 运行 用于任意数量的事件。
SELECT t1.Object
FROM yourTable t1
INNER JOIN
(
SELECT Object, MIN(Time) AS Time
FROM yourTable
GROUP BY Object
) t2
ON t1.Object = t2.Object AND
((t1.Event = 'A' AND t1.Time = t2.Time) OR
t1.Event <> 'A')
GROUP BY t1.Object
HAVING COUNT(*) = 2 -- change this count to match # of events
MySQL 演示:
试试这个:
SELECT DISTINCT object
FROM yourtable t
WHERE EXISTS
(SELECT FROM yourtable t3
WHERE t3.object = t.object
AND t3.event = 'A'
AND EXISTS
(SELECT 'B'
FROM yourtbale t4
WHERE t4.object = t3.object
AND t4.event = 'B'
AND t4.time > t3.time)
)
如果您使用的是sql-服务器:
SELECT
A.[Object]
, A.[Time]
, B.[Time]
FROM
(SELECT
Distinct [Object]
FROM
[table] AS A
WHERE
A.[Event] = 'A'
) AS A
CROSS APPLY
(SELECT
TOP 1 *
FROM
[table] AS B
WHERE
[Event] = 'B'
AND
B.[Object] = A.[Object]
AND
A.[Time] < B.[Time]) AS B
如果您只跟踪一个接一个发生的两个事件,那么您可以用一个 JOIN
.
无论 Obj1
有多少事件,这都会起作用,正如你提到的,你只对 A
和 B
存在并且一个接一个地感兴趣,分别
select distinct t1.object
from TABLE t1
inner join TABLE t2 on t1.object = t2.object
and t2.time > t1.time
and t1.event = 'A'
and t2.event = 'B'
这是代码结果的示例:
declare @tbl table (obj varchar(10), event varchar(1), time int)
insert @tbl values ('Obj1', 'A', 1), ('Obj1', 'B', 3), ('Obj2', 'A', 7), ('Obj2', 'B', 4)
select distinct t1.obj
from @tbl t1
inner join @tbl t2 on t1.obj = t2.obj
and t2.time > t1.time
and t1.event = 'A'
and t2.event = 'B'
对于 SQL 服务器:
;with A as
(select Object, MIN(Time) as Time from table where Event='A' group by Object)
, B as
(select Object, MIN(Time) aS Time from table where Event='B' group by Object)
Select A.Object from A inner join B on B.Object=A.Object where A.Time < B.Time