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.