tags:

views:

365

answers:

5

All,

I'm sure this is a pretty simple SQL query question, but I'm sure there's a good way, and a very BAD way, to do this. Left to my own devices, I'm liable to end up with the latter. So...

I have a table in Access with data that looks like this:

ID      Value  As_of
1173    156    20090601
1173    173    20081201
1173    307    20080901
1173    305    20080601
127     209    20090301
127     103    20081201
127     113    20080901
127     113    20080601
1271    166    20090201
1271    172    20081201
1271    170    20080901
1271    180    20080601
...

What I'd like to get is the "Value" for each unique ID with the most recent "As Of" date (which is in YYYYMM format).

So, my result set should look like this:

ID      Value    As_of
1173    156      20090601
127     209      20090301
1271    166      20090201

Note that different IDs will have different "As Of" dates. In other words, I can't simply indentify the most recent as of globally, then select every row with that date.

For what it's worth, this table has about 200,000 total rows, and about 10,000 unique IDs.

Many thanks in advance!

A: 

Not sure what platform you're looking to do this on, but in T-SQL you can do the following:

SELECT t.*
FROM (
    SELECT ID, MAX(As_Of) as r1
    FROM myTable
    GROUP BY ID
    ) as dt
INNER JOIN myTable t ON dt.ID = t.ID and dt.r1 = t.As_Of

Good luck!

EDIT: Well my poor answer was bothering me so i've fixed it, even though this answer already exists elsewhere on the page now.

Funka
sorry, i do see that you said Access was the db. This should still work for you I hope!
Funka
I believe you meant to group by value and ID since he is asking for the value by ID for the max date.
Ryan Cook
-1 This doesn't even reference ID, so it won't fulfill the need. It could be nested in another query and work out all right ...
Smandoli
I'm dying to understand why at least two people upvoted this answer ?
Radu094
Funka, Thanks for your response. However, it's not quite what I'm looking for. I'm trying to identify the value with the max "as_of" date FOR EACH unique ID in my table. My apologies if my original post wasn't clear.
mattstuehler
This is simply a case of me not reading the question completely. I appear to have assumed `ID` was an autonumber or identity column. You are all correct that this is incorrect! GROUP BY would be on the `ID` column, then, and you could use this in an inner query or derived table to join to get Value. I would edit my answer but it looks like there is already something correct on this page. Sorry for the confusion!
Funka
A: 

I think what you're looking for is this:

select id, value, as_of from table_name where as_of = max(as_of) group by id

This says for each id, find the max as_of, and get that value.

This is generic sql. I'm not sure about access. I'm sure if this doesn't work there is something similar.

Good luck! Joe

Joe Fair
+2  A: 

@Funka, that will not work if you have duplicate "value" values for different ID's - that will basically give you a grouped list by "value", not by id...

@Joe Fair, aggregates aren't allowed in where clauses without a subquery/having combo as well, at least not in ANSI...

This will give you the list, but will give duplicates as well if you have multiple rows with the same id/As_of values:

select  t1.id, t1.value, t1.As_of
from    tableName t1
join    (
  select id as id, max(As_of) as max_as_of
  from tableName
  group by id
 ) t2
on   t1.id = t2.id
and  t1.As_of = t2.max_as_of

If you want to remove duplicates from that, you'd just want to add a distinct to the top select, like this:

select  distinct t1.id, t1.value, t1.As_of
from    tableName t1
join    (
  select id as id, max(As_of) as max_as_of
  from tableName
  group by id
 ) t2
on   t1.id = t2.id
and  t1.As_of = t2.max_as_of
chadhoc
well, they are both corect! but where's the distinct ? :-)
Radu094
sorry, just edited to add it to the bottom query...copy/paste strikes again...
chadhoc
Chadhoc - Just wanted to thank you for this answer - it works perfectly. I'd have credited you with the "accepted answer", except I'd already given that to Radu's post. Not sure what the protocol is for that - both answers were equally useful and correct. And bother were submitted at the same time.
mattstuehler
no worries, main thing is you got an answer
chadhoc
+3  A: 

If you need both the date and the value, you need to do a join:

SELECT ID, Value,As_of 
from yourTable a inner join 
          (SELECT ID, MAX(As_of) as As_of 
          from yourTable group by ID) b 
on a.ID=b.ID and a.As_of = b.As_of
Radu094
Radu - Just wanted to thank you for this answer - works perfectly, and about 99.99% faster than the original nested "Select Max" I tried. Cheers, Matt
mattstuehler
+1  A: 

Try something like this

SELECT t1.*
FROM (SELECT Table1.ID, Max(Table1.As_Of) AS MaxOfAs_Of
FROM Table1
GROUP BY Table1.ID
)  AS MaxIDS INNER JOIN Table1 t1 ON MaxIDS.ID = t1.ID
and MaxIDS.MaxOfAs_Of = t1.As_Of
astander