2012-11-07 24 views
1

我在Microsoft SQL Server 2008如何在Microsoft SQL Server 2008中爲特定用戶選擇最新事件?

一個數據庫中,我有一個表[eventlog].[dbo].[USER_OPERATION]的列[userID], [event_description], [event_date], [event_type], [eventID]

eventID是獨一無二的,好了,每一個給定的事件可能發生。

給定UserID,當然,事件不是唯一的(每個用戶可能有很多與他有關的事件),但與單個個體用戶關聯

我想是要創建一個查詢,會給我一個列表,其中每個用戶(即每個UserID)及其相關信息(給定特定事件的event_type,eventIDevent_description)僅具有最近的事件。

舉例說明:

執行

SELECT * 
FROM [eventlog].[dbo].[USER_OPERATION] 
ORDER BY userID ASC 

當我相處的

|====================================================================================| 
| eventID | userID |  event_description  | event_date | event_type | 
|   |   |         |    |   | 
| 123  | 2  | USER 2 broke something   | 03.11.11 | CRASH | 
| 391  | 2  | USER 2 filed a complaint  | 30.04.10 | COMPLAINT | 
| 392  | 2  | USER 2 has bought beer   | 31.10.09 | PURCHASE | 
| 32  | 3  | USER 3 broke something   | 22.10.11 | CRASH | 
| 568  | 4  | USER 4 has requested support | 05.12.11 | SUPP_REQ | 
| 691  | 4  | USER 4 has bought beer   | 01.12.10 | PURCHASE | 
| 81  | 4  | USER 4 updated personal data | 17.07.11 | PDAT_UPD | 
| 141  | 5  | USER 5 has bought beer   | 16.08.11 | PURCHASE | 
| 142  | 5  | USER 5 broke something   | 16.08.11 | CRASH | 
| 269  | 6  | USER 6 updated personal data | 27.01.12 | PDAT_UPD | 
| 845  | 7  | USER 7 updated personal data | 27.01.12 | PDAT_UPD | 
|   |   |         |    |   | 
|====================================================================================| 

的線條正如你所看到的,有些用戶與他們相關聯的不同日期的多個事件東西。

我想要的是一個查詢,它會向我顯示一個用戶列表,以及用戶最近的日期是什麼(輸出本質上是一個列出每個用戶一次的表,並顯示最多與每個用戶關聯的最近事件以及關聯的event_description,event_date和event_type信息)。

讓我們調用這樣的查詢結果「最近的事件表」。

請注意用戶5(UserID 5)的「異常情況」,他們在同一天打破了某些東西併購買了啤酒。

在這種情況下,我不在乎兩個當天事件中的哪一個會進入「最近事件表」,它可以通過隨機選擇或任何(儘管我仍然需要相關的event_description和event_type信息)。

理想,結果看起來就會像這樣(爲同一組用戶的如上):

|====================================================================================| 
| eventID | userID |  event_description  | event_date | event_type | 
|   |   |         |    |   | 
| 123  | 2  | USER 2 broke something   | 03.11.11 | CRASH | 
| 32  | 3  | USER 3 broke something   | 22.10.11 | CRASH | 
| 568  | 4  | USER 4 has requested support | 05.12.11 | SUPP_REQ | 
| 141  | 5  | USER 5 has bought beer   | 16.08.11 | PURCHASE | 
| 269  | 6  | USER 6 updated personal data | 27.01.12 | PDAT_UPD | 
| 845  | 7  | USER 7 updated personal data | 27.01.12 | PDAT_UPD | 
|   |   |         |    |   | 
|====================================================================================| 

如果沒有辦法只有「挑這兩個中的任何一個隨機或按一些規則「對於用戶5的這種」日期欺騙「,在」最近事件表「中有兩個條目對於這種特殊情況是可以接受的,因爲它們非常罕見,我可以手動處理它們。

在這種(有點不那麼幸運的)情況下,「最近的事件表」看起來像

|====================================================================================| 
| eventID | userID |  event_description  | event_date | event_type | 
|   |   |         |    |   | 
| 123  | 2  | USER 2 broke something   | 03.11.11 | CRASH | 
| 32  | 3  | USER 3 broke something   | 22.10.11 | CRASH | 
| 568  | 4  | USER 4 has requested support | 05.12.11 | SUPP_REQ | 
| 141  | 5  | USER 5 has bought beer   | 16.08.11 | PURCHASE | 
| 142  | 5  | USER 5 broke something   | 16.08.11 | CRASH | 
| 269  | 6  | USER 6 updated personal data | 27.01.12 | PDAT_UPD | 
| 845  | 7  | USER 7 updated personal data | 27.01.12 | PDAT_UPD | 
|   |   |         |    |   | 
|====================================================================================| 

這也是可以接受的(但以後會需要一點額外的修剪)。

因此,總結一下我的問題,是否可以構建這樣一個Microsoft SQL查詢,該查詢可以根據上述內容爲我提供最近的事件表?

非常感謝您的幫助提前

+0

你爲什麼用mysql標籤標記? –

+0

對不起,我的一個大腦屁。固定 –

回答

1

您可以使用CTE與ROW_NUMBER()功能組合(公用表表達式):

;WITH CTE AS 
(
    SELECT 
     *, 
     RowNum = ROW_NUMBER() OVER (PARTITION BY UserID 
            ORDER BY event_date DESC, event_id DESC) 
    FROM [eventlog].[dbo].[USER_OPERATION] 
) 
SELECT * 
FROM CTE 
WHERE RowNum = 1 

這種「分區」您的數據分組 - 每個UserID - 然後按event_date DESCevent_id DESC)對這組數據中的事件進行排序,並對它們進行編號 - 最近的條目(針對每個用戶)得到RowNum = 1 - 因此只需從CTE中選擇那些你完成了!

+1

哇。據我所知(現在重複檢查),它確實需要什麼(嗯,我試着用「ORDER BY event_date DESC」)來試一試。似乎很好。非常感謝! –

+0

@Lone_passerby:不客氣! –

+0

順便說一句,marc_s,通過event_date排序後按event_id排序的人是什麼? (到目前爲止,就我所知,似乎兩種方法都行得通......) –

0
DECLARE @USER_OPERATION table 
(
eventID int, 
userID int, 
event_description nvarchar(250), 
event_date date, 
event_type nvarchar(250) 
) 
Insert into @USER_OPERATION values (123,2,'USER 2 broke something','11/03/11','CRASH') 
Insert into @USER_OPERATION values (391,2,'USER 2 filled a complaint','04/30/10','COMPLAINT') 
Insert into @USER_OPERATION values (392,2,'USER 2 bought beer','10/31/09','PURCHASE') 
Insert into @USER_OPERATION values (32,3,'USER 3 broke something','10/22/11','CRASH') 
Insert into @USER_OPERATION values (568,4,'USER 4 has requested support','12/05/11','SUPP_REQ') 
Insert into @USER_OPERATION values (691,4,'USER 4 has bought beer','12/01/10','PURCHASE ') 
Insert into @USER_OPERATION values (81,4,'USER 4 updated personal data','07/17/11','PDAT_UPD ') 
Insert into @USER_OPERATION values (141,5,' USER 5 has bought beer','08/16/11','PURCHASE') 
Insert into @USER_OPERATION values (142,5,' USER 5 broke something','08/16/11','CRASH') 
Insert into @USER_OPERATION values (269,6,'USER 6 updated personal data','01/27/12','PDAT_UPD') 
Insert into @USER_OPERATION values (845,7,'USER 7 updated personal data ','01/27/12','PDAT_UPD') 


SELECT * FROM @USER_OPERATION AS userOp INNER JOIN 
(SELECT DISTINCT userID, (SELECT Top 1 eventID FROM @USER_OPERATION a WHERE a.userID =B.userID ORDER BY event_date DESC)as eventID 
from @USER_OPERATION AS B) as tbl 
ON userOp.userID =tbl.userID and userOp.eventID =tbl.eventID