在SQL Server 2008中按用户名选择最新的记录组

时间:2012-04-23 08:22:57

标签: sql sql-server-2008 tsql

我有一张包含这些数据的表格:

ID   voting_ID   username   timestamp              XMLBallot
1    9           voter01    23. 4. 2012 8:54:45    xmldata
2    9           voter01    21. 4. 2012 14:00:34   xmldata
3    9           voter02    20. 4. 2012 16:01:10   xmldata
4    11          voter01    23. 4. 2012 8:40:45    xmldata
5    9           voter03    19. 4. 2012 21:18:49   xmldata

我需要为特定voting_ID中的每个选民(用户名)只获得一张最新的选票。

例如,我需要为@voting_ID=9

返回数据
ID   voting_ID   username   timestamp              XMLBallot
1    9           voter01    23. 4. 2012 8:54:45    xmldata
3    9           voter02    20. 4. 2012 16:01:10   xmldata
5    9           voter03    19. 4. 2012 21:18:49   xmldata

请帮我构建一下SQL Server 2008查询..谢谢 PS:表名是ballots

4 个答案:

答案 0 :(得分:5)

您可以在此处使用多个选项,但使用ROW_NUMBER分组user并在timestamp上排序(降序)可以轻松选择最新记录。

使用ROW_NUMBER

SELECT *
FROM   (
         SELECT ID, voting_ID, username, timestamp, XMLBallot
                , rn = ROW_NUMBER() OVER (PARTITION BY voting_ID, username ORDER BY timestamp DESC)
         FROM   Ballots
       ) bt 
WHERE  rn = 1

或者,您可以选择每个用户的最大时间戳并加入其中。

使用MAX

SELECT bt.ID, bt.voting_ID, bt.username, bt.timestamp, bt.XMLBallot
FROM   Ballots bt
       INNER JOIN (
          SELECT username, voting_ID, timestamp = MAX(timestamp)
          FROM   Ballots
          GROUP BY
                 username, voting_ID
        ) btm ON btm.username = bt.Username
                 AND btm.voting_ID = bt.voting_ID
                 AND btm.timestamp = bt.timestamp

答案 1 :(得分:1)

也许是这样的:

测试数据

DECLARE @T TABLE
    (
        ID INT,
        voting_ID int, 
        username VARCHAR(100),
        timestamp VARCHAR(100),
        XMLBallot VARCHAR(100)
    )

INSERT INTO @T
VALUES
    (1,9,'voter01','23. 4. 2012 8:54:45','xmldata'),
    (2,9,'voter01','21. 4. 2012 14:00:34','xmldata'),
    (3,9,'voter02','20. 4. 2012 16:01:10','xmldata'),
    (4,11,'voter01','23. 4. 2012 8:40:45','xmldata'),
    (5,9,'voter03','19. 4. 2012 21:18:49','xmldata')

<强>查询

DECLARE @voting_ID INT=9
;WITH CTE
AS
(   
    SELECT
        ROW_NUMBER() OVER(PARTITION BY username ORDER BY voting_ID) AS RowNbr,
        t.*
    FROM
        @T AS t
)
SELECT
    *
FROM
    CTE
WHERE
    RowNbr=1
    AND CTE.voting_ID=@voting_ID

<强> EDIT1

也许这样的话:

DECLARE @voting_ID INT=9
;WITH CTE
AS
(   
    SELECT
        ROW_NUMBER() OVER(PARTITION BY username ORDER BY timestamp DESC) AS RowNbr,
        t.*
    FROM
        @T AS t
    WHERE
        t.voting_ID=@voting_ID
)
SELECT
    *
FROM
    CTE
WHERE
    RowNbr=1

答案 2 :(得分:1)

替代方法。

WITH sub 
     AS (SELECT *, 
                Max(timestamp) OVER (partition BY company) AS latest 
         FROM   ballots) 
SELECT * 
FROM   sub 
WHERE  latest = timestamp 

答案 3 :(得分:-1)

select  t1_4.ID, t1_4.voting_id, t1_4.timestamp, t1_4.xmlballot
from   table1 as t1_4
where   t1_4.ID in (  SELECT  id_to_select
            from   (  SELECT  (  SELECT t1_1.ID
                        from   table1 as t1_1 
                        where t1_1.id =  (    SELECT  top 1 t1_2.ID
                                  from     table1 as t1_2
                                  where   t1_2.username = t1_3.username
                                  order by timestamp desc)
                      ) as id_to_select, 
                      t1_3.username
                  from   table1 as t1_3
                  group by username)
          )