Reputation: 5695
I have a SQL Server table that has project_id int,update_date datetime ,update_text varchar(max)
The table has many updates per project_id. I need to fetch the latest by update_date for all project_id values.
Example:
project_id update_date update_text 1 2017/01/01 Happy new year. 2 2017/01/01 Nice update 2 2017/02/14 Happy Valentine's 3 2016/12/25 Merry Christmas 3 2017/01/01 A New year is a good thing
The query should get:
project_id update_date update_text 1 2017/01/01 Happy new year. 2 2017/02/14 Happy Valentine's 3 2017/01/01 A New year is a good thing
Upvotes: 5
Views: 19174
Reputation: 11
Note to top answer:
Whilst some may say it is the best answer it will often not be the most efficient query time. In my data the following example is an order of magnitude faster.
SELECT
project_id, update_date, update_text
FROM
projects P
WHERE
update_date = (SELECT MAX(update_date) FROM projects WHERE project_id = P.project_id)
(If you can have more than one update on a given date then would need max on update_text and group by as in this specific example you would not know which update_text value was valid.)
Upvotes: 1
Reputation: 14928
You can do it as:
with CTE as(
SELECT project_id, MAX(update_date) update_date
FROM YourTable
GROUP BY project_id
)
SELECT cte.project_id, cte.update_date , max(t.update_text) update_text
FROM YourTable T inner join CTE on T.project_id = CTE.project_id
group by cte.project_id, cte.update_date ;
Demo.
Upvotes: 0
Reputation: 38063
using top with ties
with row_number()
select top 1 with ties
project_id, update_date, update_text
from projects
order by row_number() over (partition by project_id order by update_date desc)
rextester demo: http://rextester.com/MGUNU86353
returns:
+------------+-------------+----------------------------+
| project_id | update_date | update_text |
+------------+-------------+----------------------------+
| 1 | 2017-01-01 | Happy new year. |
| 2 | 2017-02-14 | Happy Valentine's |
| 3 | 2017-01-01 | A New year is a good thing |
+------------+-------------+----------------------------+
Upvotes: 12
Reputation: 1647
You can find the MAX(date)
like:
SELECT * FROM [table]
INNER JOIN (SELECT project_id, date = MAX(update_date) FROM [table] GROUP BY project_id) AS a
ON [table].project_id = a.project_id AND update_date = date
or you can use ROW_NUMBER()
like:
SELECT * FROM (
SELECT *, rownum = ROW_NUMBER() OVER (PARTITION BY project_id ORDER BY
update_date DESC) FROM [table]
) AS a WHERE rownum = 1
Upvotes: 1
Reputation: 48048
This query will give you the latest date for each project
Select Project_Id, Max (Update_Date) Max_Update_Date
From MyTable
Group By Project_Id
So join it back to the original table
Select Project_Id, Update_Date, Update_Text
From MyTable
Inner Join
(
Select Project_Id, Max (Update_Date) Max_Update_Date
From MyTable
Group By Project_Id
) MaxDates
On MyTable.Project_Id = MaxDates.Project_Id
And MyTable.Update_Date = MaxDates.Max_Update_Date
Upvotes: 1