简体   繁体   中英

Select newest record group by username in SQL Server 2008

I have a table with this data:

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

I need to get only one newest ballot for each voter (username) in specific voting_ID .

For example data I need to be returned for @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

Please help me build that SQL Server 2008 query.. thank you PS: table name is ballots

You have several options here but using adding a ROW_NUMBER grouped by user and sorted (descending) on your timestamp allows you to easily select the latest records.

Using 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

Alternatively, you can select the maximum timestamp per user and join on that.

Using 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

Maybe something like this:

Test data

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')

Query

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

Maybe something like this then:

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

Alternative way to do it.

WITH sub 
     AS (SELECT *, 
                Max(timestamp) OVER (partition BY company) AS latest 
         FROM   ballots) 
SELECT * 
FROM   sub 
WHERE  latest = timestamp 
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)
          )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM