dbTalk Databases Forums  

Aggregate Fun (Getting the Max out of MAX)...head scratcher

comp.databases.ms-sqlserver comp.databases.ms-sqlserver


Discuss Aggregate Fun (Getting the Max out of MAX)...head scratcher in the comp.databases.ms-sqlserver forum.



Reply
 
Thread Tools Display Modes
  #1  
Old   
sean.pinto@gmail.com
 
Posts: n/a

Default Aggregate Fun (Getting the Max out of MAX)...head scratcher - 11-06-2007 , 06:56 PM






Ok, so I have had this problem more than once and can't think of a
GOOD way to do it. Say I have a table with containing membership
information (primary key, customer number, inception date,
organization number). For each customer, they can have many
memberships across different organizations as well as the same
organization. What I want to know is how to get all the columns of
the table ONCE for each customer but containing the information of the
most recent row grouped by the customer.

Example:

key_no | customer_no | inception_date | org_no
1 1 1/1/2001 1
2 1 2/1/2000 2
3 2 3/13/2005 1
4 2 3/11/2005 1
5 2 12/12/2006 2
6 3 1/1/2001 3
7 4 2/2/2000 1
8 5 6/6/2006 4
9 5 7/23/2000 1


Results:

key_no | customer_no | inception_date | org_no
1 1 1/1/2001 1
5 2 12/12/2006 2
6 3 1/1/2001 3
8 5 6/6/2006 4
9 5 7/23/2000 1


Now initially I was doing something like the following under the
assumption that the key_no's would be auto-incremented so the largest
key_no was the most recent row.

SELECT *
FROM tx_cust_memb cm
JOIN
(SELECT MAX(key_no) AS key_no
FROM tx_cust_memb cmInner
GROUP BY customer_no) derived
ON derived.key_no = cm.key_no


However, what if someone updated the inception date of a row due to a
mistake? I am looking for a basically a way to do grab the TOP 1 key
of a grouping ordering by another column. And do so in a concise and
clean way. I feel like there is a way to do it with the ROW_NUMBER()
OVER clause but don't know how. Please help!

Thanks,
Sean


Reply With Quote
  #2  
Old   
Plamen Ratchev
 
Posts: n/a

Default Re: Aggregate Fun (Getting the Max out of MAX)...head scratcher - 11-06-2007 , 09:37 PM






Hi Sean,

Here is one way to do this (if I understand correctly your requirements) in
SQL Server 2005 using ROW_NUMBER. Based on your notes I assumed the latest
inception date can be used to identify the most recent update.

WITH cte
(key_no, customer_no, inception_date, org_no, seq_no)
AS
(
SELECT key_no, customer_no, inception_date, org_no,
ROW_NUMBER() OVER(
PARTITION BY customer_no
ORDER BY inception_date DESC,
key_no DESC) AS seq_no
FROM tx_cust_memb
)
SELECT key_no, customer_no, inception_date, org_no
FROM cte
WHERE seq_no = 1;

BTW, your results seem to be incorrect, you have customer 5 listed twice and
customer 4 is missing.

HTH,

Plamen Ratchev
http://www.SQLStudio.com



Reply With Quote
  #3  
Old   
Ed Murphy
 
Posts: n/a

Default Re: Aggregate Fun (Getting the Max out of MAX)...head scratcher - 11-07-2007 , 01:37 AM



sean.pinto (AT) gmail (DOT) com wrote:

Quote:
Ok, so I have had this problem more than once and can't think of a
GOOD way to do it. Say I have a table with containing membership
information (primary key, customer number, inception date,
organization number). For each customer, they can have many
memberships across different organizations as well as the same
organization. What I want to know is how to get all the columns of
the table ONCE for each customer but containing the information of the
most recent row grouped by the customer.

Example:

key_no | customer_no | inception_date | org_no
1 1 1/1/2001 1
2 1 2/1/2000 2
3 2 3/13/2005 1
4 2 3/11/2005 1
5 2 12/12/2006 2
6 3 1/1/2001 3
7 4 2/2/2000 1
8 5 6/6/2006 4
9 5 7/23/2000 1


Results:

key_no | customer_no | inception_date | org_no
1 1 1/1/2001 1
5 2 12/12/2006 2
6 3 1/1/2001 3
8 5 6/6/2006 4
9 5 7/23/2000 1
select *
from the_table t1
where not exists (
select *
from the_table t2
where t2.customer_no = t1.customer_no
and (t2.inception_date > t1.inception_date
or (t2.inception_date = t1.inception_date
and t2.key_no > t1.key_no))
)


Reply With Quote
  #4  
Old   
sean.pinto@gmail.com
 
Posts: n/a

Default Re: Aggregate Fun (Getting the Max out of MAX)...head scratcher - 11-07-2007 , 11:41 AM



On Nov 6, 7:37 pm, "Plamen Ratchev" <Pla... (AT) SQLStudio (DOT) com> wrote:
Quote:
Hi Sean,

Here is one way to do this (if I understand correctly your requirements) in
SQL Server 2005 using ROW_NUMBER. Based on your notes I assumed the latest
inception date can be used to identify the most recent update.

WITH cte
(key_no, customer_no, inception_date, org_no, seq_no)
AS
(
SELECT key_no, customer_no, inception_date, org_no,
ROW_NUMBER() OVER(
PARTITION BY customer_no
ORDER BY inception_date DESC,
key_no DESC) AS seq_no
FROM tx_cust_memb
)
SELECT key_no, customer_no, inception_date, org_no
FROM cte
WHERE seq_no = 1;

BTW, your results seem to be incorrect, you have customer 5 listed twice and
customer 4 is missing.

HTH,

Plamen Ratchevhttp://www.SQLStudio.com
This is PERFECT! Thanks so much!

Sean



Reply With Quote
Reply




Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.3
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.