1

我在 Microsoft SQL Server 2008 中有一个数据库

我有一个[eventlog].[dbo].[USER_OPERATION]有列的表[userID], [event_description], [event_date], [event_type], [eventID]

eventID对于每个可能发生的给定事件来说都是独一无二的。

给定UserID的事件当然不是唯一的(每个用户可能有很多与他相关联的事件),而是与单个用户相关联

我想要的是创建一个查询,它会给我一个列表,其中只有每个用户的最新事件(也就是说,every UserID)及其相关信息(给定特定事件event_typeeventID和)。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 信息)。

我们将这样的查询结果称为“最近事件表”。

请注意用户 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 查询,它会按照上面描述的方式给我一个最近的事件表?

非常感谢您提前提供的帮助

4

2 回答 2

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然后按 and 对该组数据中的事件进行排序event_date DESCevent_id DESC并对它们进行编号 - 最近的条目(对于每个用户)获得RowNum = 1- 所以只需从 CTE 和你完成了!

于 2012-11-07T09:39:04.827 回答
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
于 2012-11-07T10:04:23.180 回答