Reputation: 8276
I have a similar table:
ID | Name | Time
-------|---------|-----------------------------
111 | AAA | 2015-11-05 15:39:24.000
222 | BBB | 2015-11-04 11:29:11.000
111 | AAA | 2015-11-02 13:12:10.000
333 | CCC | 2015-11-05 15:39:24.000
111 | AAA | 2015-11-01 15:39:24.000
I would like to get the latest Time
for every ID
. My output would look something like this:
ID | Name | Time
-------|---------|-----------------------------
111 | AAA | 2015-11-05 15:39:24.000
222 | BBB | 2015-11-04 11:29:11.000
333 | CCC | 2015-11-05 15:39:24.000
Please help me formulate the query!
Can I use max(Time)
to get latest Time
?
Do I need to JOIN the table with itself to be able to list max(Time)
for all ID
s?
Upvotes: 1
Views: 76
Reputation: 460048
If there are more columns you want to keep you could use a CTE with ROW_NUMBER
function:
WITH CTE AS
(
SELECT Id, Name, Time, OtherColumns...,
RN = ROW_NUMBER() OVER (PARTITION BY ID Order By Time DESC)
FROM dbo.TableName
)
SELECT Id, Name, Time, OtherColumns...
FROM CTE
WHERE RN = 1
If it's possible that there are mutliple rows with the same max-time per ID and you want all of them instead of one arbitrary replace ROW_NUMBER
with DENSE_RANK
. Ranking Functions
Upvotes: 4
Reputation: 375
Your question does not say that you want to get your output based on NAME
, just ID
. Therefore the previous answers are technically wrong. You should be using:
SELECT ID, AGGREGATEFUNCTION(Name), MAX(Time) AS [Time]
FROM Your_Table
GROUP BY ID
This means if your names differ then they will not create a separate group.
It also meets exactly your requirement.
Upvotes: 1
Reputation: 175586
You can use MAX
function:
SELECT ID, Name, MAX([Time]) AS [Time]
FROM your_table
GROUP BY ID, Name ;
Output:
╔═════╦══════╦═════════════════════╗
║ ID ║ Name ║ Time ║
╠═════╬══════╬═════════════════════╣
║ 111 ║ AAA ║ 2015-11-05 15:39:24 ║
║ 222 ║ BBB ║ 2015-11-04 11:29:11 ║
║ 333 ║ CCC ║ 2015-11-05 15:39:24 ║
╚═════╩══════╩═════════════════════╝
There is one catch though, data you provided has the same ID/NAME pairs. With different data you will get:
INSERT INTO #Your_Table(ID,Name,Time) VALUES (111,'AAA','2015-11-05 15:39:24.000');
INSERT INTO #Your_Table(ID,Name,Time) VALUES (222,'BBB','2015-11-04 11:29:11.000');
INSERT INTO #Your_Table(ID,Name,Time) VALUES (111,'AAA','2015-11-02 13:12:10.000');
INSERT INTO #Your_Table(ID,Name,Time) VALUES (333,'CCC','2015-11-05 15:39:24.000');
INSERT INTO #Your_Table(ID,Name,Time) VALUES (111,'DDD','2015-11-01 15:39:24.000');
Output:
╔═════╦══════╦═════════════════════╗
║ ID ║ Name ║ Time ║
╠═════╬══════╬═════════════════════╣
║ 111 ║ AAA ║ 2015-11-05 15:39:24 ║
║ 222 ║ BBB ║ 2015-11-04 11:29:11 ║
║ 333 ║ CCC ║ 2015-11-05 15:39:24 ║
║ 111 ║ DDD ║ 2015-11-01 15:39:24 ║
╚═════╩══════╩═════════════════════╝
If you want actual row and not result of grouping use like here:
WITH cte AS
(
SELECT ID, MAX([Time]) AS [Time]
FROM #your_table
GROUP BY ID
)
SELECT t.*
FROM #your_table t
JOIN cte c
ON c.ID = t.ID
AND c.[Time] = t.[Time]
Upvotes: 1
Reputation: 11556
Use MAX
function to find the latest time.
Query
SELECT ID, Name,
MAX(Time) AS [Time]
FROM your_table_name
GROUP BY ID, Name;
Upvotes: 2