Get distinct max date using SQL
I'm not sure quite how to title my question but this is what I'm trying to do:
Given pc_tmppl_tbl
pc_tmppl_attach pc_tmppl_val1 pc_tmppl_crtdt
AJC05-06 AJCINT 2005-08-15 10:32:03.790
AJC06-07 AJCINT 2006-10-17 10:02:06.570
AJC07-08 AJCINT 2007-06-13 10:44:53.573
AJC08-09 AJCINT 2008-06-27 09:51:17.290
AJC09-10 AJCINT 2009-07-20 14:26:06.270
AJC10-11 AJCINT 2010-08-26 11:54:32.777
AJC99-001 AJCINT 2005-05-30 19:30:51.623
ALPI05-06 ALPINE 2005-05-30 19:30:51.623
ALPI07-08 ALPINE 2006-12-11 13:57:09.923
ALPI07-08 ALPINE 2007-05-24 14:04:07.867
ALPI08-09 ALPINE 2008-04-30 09:49:24.140
I want it to return the max date for pc_tmppl_crtdt and its corresponding pc_tmppl_attach so
ALPI08-09 ALPINE 2008-04-30 09:49:24.140
AJC10-11 AJCINT 2开发者_运维技巧010-08-26 11:54:32.777
I've been trying sub queries but haven't quite hit on the answer, any help would be much appreciated.
Select T.pc_tmppl_attach, T.pc_tmppl_val1, T.pc_tmppl_crtdt
From pc_temppl_tbl As T
Join (
Select pc_tmppl_val1, Max( T1.pc_tmppl_crtdt ) As MaxDateTime
From pc_temppl_tbl As T1
Group By T1.pc_tmppl_val1
) As Z
On Z.pc_tmppl_val1 = T.pc_tmppl_val1
And Z.MaxDateTime = T.pc_tmppl_crtdt
You didn't define what server and version you're using - if you're on SQL Server 2005 or newer, you can use a CTE (Common Table Expression) and a ranking function - something like this:
;WITH PartitionedData AS
(
SELECT
pc_tmppl_attach, pc_tmppl_val1, pc_tmppl_crtdt,
ROW_NUMBER() OVER(PARTITION BY pc_tmppl_val1
ORDER BY pc_tmppl_crtdt DESC) AS 'RowNumber'
FROM dbo.pc_tmppl_tbl
)
SELECT
pc_tmppl_attach, pc_tmppl_val1, pc_tmppl_crtdt
FROM
PartitionedData
WHERE
RowNumber = 1
Basically, what the CTE (inner select) does is grab all data from your table, partition it by your column pc_tmppl_val1
- so each group of values for pc_tmppl_val1
starts counting back at 1 - and order those entries by pc_tmppl_crtdt
descending - newest entry is first.
So for each pc_tmppl_val1
value, the newest entry is the entry with the RowNumber = 1
and that's what the outer SELECT
(based on the CTE) gives you.
The CTE and ranking function are very flexible, too - if you need to top 3 entries for each pc_tmppl_val1
value, just change the outer WHERE
condition to
WHERE RowNumber <= 3
and you're done!
The CTE (Common Table Expression) and ranking functions are ANSI SQL standard - so other databases besides Microsoft SQL Server support it, too (I just know SQL Server the best - that's why I use it as a sample).
Using a correlated query (which should work with most sql databases):
SELECT pc_tmppl_attach,pc_tmppl_val1, pc_tmppl_crtdt
FROM pc_tmppl_tbl AS tbl_ext
WHERE pc_tmppl_crtdt = (
SELECT MAX(tbl_int.pc_tmppl_crtdt)
FROM pc_tmppl_tbl AS tbl_int
WHERE tbl_int.pc_tmppl_val1 = tbl_ext.pc_tmppl_val1
)
SELECT TOP 1 [pc_tmppl_attach], [pc_tmppl_crtdt]
FROM [Given pc_tmppl_tbl]
order by pc_tmppl_crtdt desc
精彩评论