我在Microsoft SQL Server 2008中有一个数据库
我有一个表[eventlog].[dbo].[USER_OPERATION]
,其中包含[userID], [event_description], [event_date], [event_type], [eventID]
列
eventID
对于每一个可能发生的特定事件都是独一无二的。
给定的UserID
当然不是唯一的事件(每个用户可能有很多与他相关的事件)但与单个用户相关联
我想要的是创建一个查询,该查询会为我提供一个列表,其中只包含每个用户的最新事件(也就是说,每个UserID
)及其相关信息(特定事件的event_type
,eventID
和event_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 info)。
我们将这样的查询结果称为“最近事件表”。
请注意用户5(用户ID 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 :(得分: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 DESC
和event_id DESC
对该数据组内的事件进行排序并对其进行编号 - 最近的条目(对于每个用户)获得RowNum = 1
- 所以只需从CTE中选择那些就完成了!
答案 1 :(得分: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