2014-10-11 62 views
1

我在SQLServer中有一個下表(簡化版)。SQL查詢:使用元組列表搜索

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

當前實現檢索來自活動表中的所有記錄,並不會在Java代碼中搜索。我希望我可以推動這個邏輯到SQL。但是如何?

我正在使用MyBatis框架來創建SQL查詢,以便元組可以內聯到查詢中。

+0

你計劃如何通過元組? – 2014-10-11 05:30:09

回答

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這裏的。它確保所有原始行都在結果集中,即使沒有匹配。

0

通過爲(用戶,時間戳)元組聲明一個表值參數類型,編寫一個表值用戶定義函數應該很簡單,該函數通過加入參數表和Events表來返回所需的結果。請參閱http://msdn.microsoft.com/en-us/library/bb510489.aspx

由於您正在使用MyBatis,因此只需爲查詢中的內聯元組生成一個表變量並加入即可能更容易。

1

喬納斯和戈登的答案讓我走上了正軌,我想。

這裏是查詢似乎做的工作:

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 
+0

您可以將過濾器的時間窗口部分修改爲:'#SEARCH_PARAMETERS。「時間戳」事件之間。輸入和合並(Events.Exited,#SEARCH_PARAMETERS。「Timestamp」)' – JohnLBevan 2014-10-12 10:51:16