我在SQLServer中有一个下表(简化版)。
Table Events
-----------------------------------------------------------
| Room | User | Entered | Exited |
-----------------------------------------------------------
| A | Jim | 2014-10-10T09:00:00 | 2014-10-10T09:10:00 |
| B | Jim | 2014-10-10T09:11:00 | 2014-10-10T09:22:30 |
| A | Jill | 2014-10-10T09:00:00 | NULL |
| C | Jack | 2014-10-10T09:45:00 | 2014-10-10T10:00:00 |
| A | Jack | 2014-10-10T10:01:00 | NULL |
.
.
.
我需要创建一个查询,在给定的时间戳中返回人的行踪。 举个例子:哪里(吉姆在2014-10-09T09:05:00),(吉姆在2014-10-10T09:01:00),(吉尔在2014-10-10T09:10:00),...
结果集必须包含给定的用户和时间戳以及找到的房间(如果有)。
------------------------------------------
| User | Timestamp | WasInRoom |
------------------------------------------
| Jim | 2014-10-09T09:05:00 | NULL |
| Jim | 2014-10-09T09:01:00 | A |
| Jim | 2014-10-10T09:10:00 | A |
用户 - 时间戳元组的数量可以是> 10 000.
当前实现从Events表中检索所有记录,并在Java代码中进行搜索。我希望我能把这个逻辑推向SQL。但是如何?
我正在使用MyBatis框架来创建SQL查询,因此可以将元组内联到查询中。
答案 0 :(得分:1)
基本查询是:
select e.*
from events e
where e.user = 'Jim' and '2014-10-09T09:05:00' >= e.entered and ('2014-10-09T09:05:00' <= e.exited or e.exited is NULL) or
e.user = 'Jill' and '2014-10-10T09:10:00 >= e.entered and ('2014-10-10T09:10:00' <= e.exited or e.exited is NULL) or
. . .;
SQL Server可以处理大量可疑的查询,因此您可以继续这样做。但是,如果表中已有名称/时间值(或者是查询结果),则使用join
:
select ut.*, t.*
from usertimes ut left join
events e
on e.user = ut.user and
ut.thetime >= et.entered and (ut.thetime <= exited or ut.exited is null);
请注意此处使用left join
。它确保所有原始行都在结果集中,即使没有匹配项也是如此。
答案 1 :(得分:1)
我认为Jonas和Gordon的答案让我走上正轨。
这是一个似乎可以完成工作的查询:
CREATE TABLE #SEARCH_PARAMETERS(User VARCHAR(16), "Timestamp" DATETIME)
INSERT INTO #SEARCH_PARAMETERS(User, "Timestamp")
VALUES
('Jim', '2014-10-09T09:05:00'),
('Jim', '2014-10-10T09:01:00'),
('Jill', '2014-10-10T09:10:00')
SELECT #SEARCH_PARAMETERS.*, Events.Room FROM #SEARCH_PARAMETERS
LEFT JOIN Events
ON #SEARCH_PARAMETERS.User = Events.User AND
#SEARCH_PARAMETERS."Timestamp" > Events.Entered AND
(Events.Exited IS NULL OR Events.Exited > #SEARCH_PARAMETERS."Timestamp"
DROP TABLE #SEARCH_PARAMETERS
答案 2 :(得分:0)
通过声明(user,timestamp)元组的表值参数类型,编写一个表值用户定义函数应该很简单,该函数通过连接参数表和Events表返回所需的结果。见http://msdn.microsoft.com/en-us/library/bb510489.aspx
由于您正在使用MyBatis,因此可能更容易为查询中的元组内联生成元组表变量并加入其中。