【问题标题】:Select newest record group by username in SQL Server 2008在 SQL Server 2008 中按用户名选择最新的记录组
【发布时间】:2015-07-19 21:42:56
【问题描述】:

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

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

【问题讨论】:

    标签: sql sql-server-2008 tsql


    【解决方案1】:

    您在此处有多种选择,但使用添加按user 分组并在您的timestamp 上排序(降序)的ROW_NUMBER 可以让您轻松选择最新记录。

    使用 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
    

    【讨论】:

    • 您的替代解决方案的 INNER JOIN 中似乎缺少 GROUP BY
    • @AzizShaikh - 感谢您发现...今天是星期一,我能说什么
    • 谢谢,但这不适用于其他voting_ID .. 当我尝试通过voting_ID = 11 f.ex 选择记录时,仅选择voting_ID = 9 ..没有任何回报..
    • @Gondy - 这将返回voter 的最新记录,而不是voting_ID。我已更改我的答案以包含voting_ID
    • 谢谢..在第一个替代方案中将 WHERE clausule 更新为WHERE rn = 1 AND bt.voting_ID=@votingID 后,它最终可以工作了..
    【解决方案2】:

    可能是这样的:

    测试数据

    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
    

    【讨论】:

    • 我可以在哪里传递voting_ID参数?我只需要从特定投票中选择选票
    • @Gondy - 您可以将其添加到 where 子句中,变为 where RowNbr = 1 AND voting_ID = @Voting_ID
    • 谢谢,但对我不起作用..返回不是最新的时间戳,@votingID=11 不返回任何行:(
    【解决方案3】:

    另一种方法。

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

    【讨论】:

      【解决方案4】:
      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)
                )
      

      【讨论】:

        猜你喜欢
        • 2011-09-13
        • 1970-01-01
        • 2020-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-22
        相关资源
        最近更新 更多