?
Solved

Select Top 5 For Each Group - subquery syntax bug

Posted on 2006-06-23
14
Medium Priority
?
1,704 Views
Last Modified: 2008-01-09
Hi all - painfully stumped for a Friday.  Trying to implement any of these three previous solutions to 'selecting top x for each group' type problem: Select top members with most claims total for each group (Last_Name).

Member_ID   Last_Name   Total
001              Palmetto         12
002              Trident            10
003              Palmetto          9
004              Macy               4
005              Macy               1
006              Macy               9

Result (for Top 1):
001          Palmetto    12
002          Trident       10
006          Macy          9

Templates:
http://www.experts-exchange.com/Databases/MS_Access/Q_21464877.html
http://www.experts-exchange.com/Databases/MS_Access/Q_20729610.html
http://www.experts-exchange.com/Databases/MS_Access/Q_10699721.html (paasky's 12:30 comment)

all of which use basic subquery structure which i copied to use below like:

SELECT MEMBER_ID, LAST_NAME, TOTAL
FROM q_RxSav_7s2_MembersClaimsActivity AS Q1
WHERE  TOTAL IN
   (SELECT TOP 2 Q2.TOTAL
FROM q_RxSav_7s2_MembersClaimsActivity AS Q2
WHERE Q1.LAST_NAME = Q2.LAST_NAME
ORDER BY Q2.CLAIMS DESC)

and which is causing me endless grief in Access2000 - either undefined syntax err, does not recognize 'Q1.LAST_NAME' as valid, or missing 'EXSISTS' instead of where in - none of which i can get to work.

any ideas??

thanks, wes



0
Comment
Question by:new_wes
  • 5
  • 4
  • 3
  • +1
14 Comments
 
LVL 34

Expert Comment

by:jefftwilley
ID: 16972394
This returned the Highest Value for each grouped name

SELECT [Table].lastname, Max([Table].total) AS MaxOftotal FROM Table GROUP BY [Table].lastname;
0
 

Author Comment

by:new_wes
ID: 16972465
hmm - pretty nice, but actually need to see top 20-25 for each Last_Name - can't think of any way to adjust yours for that?

oh, and also, 100's of Last_Name 's when grouped, so no union queries for each group either.  only about 50k records overall currently, shouldn't go over few mil in long run.
0
 
LVL 34

Expert Comment

by:jefftwilley
ID: 16972518
there's Always a way!! lol

SELECT TOP 25 [_Top2].lastname, Max([_Top2].total) AS MaxOftotal FROM _Top2 GROUP BY [_Top2].lastname;
0
Restore individual SQL databases with ease

Veeam Explorer for Microsoft SQL Server delivers an easy-to-use, wizard-driven interface for restoring your databases from a backup. No expert SQL background required. Web interface provides a complete view of all available SQL databases to simplify the recovery of lost database

 
LVL 34

Expert Comment

by:jefftwilley
ID: 16972545
this pulls the highest for joe, then the highest for sam, and the highest for tom...etc...top 25 being the highest totals.

This one sorts it highest to lowest

SELECT TOP 25 [_Top2].lastname, Max([_Top2].total) AS MaxOftotal FROM _Top2 GROUP BY [_Top2].lastname ORDER BY Max([_Top2].total) DESC;
0
 
LVL 34

Expert Comment

by:jefftwilley
ID: 16972559
Let me be sure I understand correctly...patients for the feeble minded.

You have bob in your table 100 times. He's got 100 values. you want bob's top 25, then you move to sam, etc.. Cause if that's what you are trying to do...then I'm tupid. I didn't do it like that.
J
0
 
LVL 54

Expert Comment

by:nico5038
ID: 16972723
Did you try:

SELECT MEMBER_ID, LAST_NAME, TOTAL
FROM q_RxSav_7s2_MembersClaimsActivity Q1
WHERE  TOTAL IN
   (SELECT TOP 2 Q2.TOTAL
FROM q_RxSav_7s2_MembersClaimsActivity Q2
WHERE Q1.LAST_NAME = Q2.LAST_NAME
ORDER BY Q2.CLAIMS DESC)

I think access doesn't like AS for qualifying tables...

Nic;o)
0
 

Author Comment

by:new_wes
ID: 16972732
just realized same thing!  i need top 25 for sam, then top 25 for bob etc.  i think that's what they were trying to do with subquery: pull each group, and then for each group pull top 25  where group=group . . .

thanks for trying though!
0
 
LVL 34

Expert Comment

by:jefftwilley
ID: 16972753
you're going to have to code this one.

list of names
    get first name
          Get top 25 values for this name
                 Put them somewhere
     get next name
loop


something like that.
0
 
LVL 54

Assisted Solution

by:nico5038
nico5038 earned 200 total points
ID: 16972759
When you want multiple fields (like memberID and Name) check my answer to: http://www.experts-exchange.com/Databases/MS_Access/Q_21890429.html

Nic;o)
0
 
LVL 58

Accepted Solution

by:
harfang earned 1800 total points
ID: 16972780
Hello new_wes

Given your sample data, you must use Member_ID as link field, not Totals. On the other hand, I find it very strange that you have several different Member_ID's for the same name...

Anyway:

SELECT MEMBER_ID, LAST_NAME, TOTAL
FROM q_RxSav_7s2_MembersClaimsActivity AS Q1
WHERE  MEMBER_ID IN
   (SELECT TOP 2 MemberID
   FROM q_RxSav_7s2_MembersClaimsActivity AS Q2
   WHERE LAST_NAME = Q1.LAST_NAME
   ORDER BY TOTAL DESC)

If that doesn't work, it's probably because you have a query that is not compatible as a subquery. Try to rewrite this based on the tables, not q_RxSav_7s2_MembersClaimsActivity. Or it will be impossible to debug.

(°v°)
0
 

Author Comment

by:new_wes
ID: 16984847
hi nico - thanks for the link - it came in handy.  

harfang, it was your comment about incompatible subqueries that saved that day!  When i take the source query and change it to make-table (because it's based on about 3 layers of other queries), then run the "top" query on that resulting table instead of the source query, it runs fine!!  quite frustrated with the lack of any error messages from access, but then again, realize it's probably doing more than expected, so will just have to live with that!

thanks very much all -

wes
0
 
LVL 58

Expert Comment

by:harfang
ID: 16985264
Thank you, new_wes.

As a matter of fact, using temp tables is a very common technique on large databases, and it's often the fastest (or the only) way. The reason is that relatively simple queries can be optimized, while a "four layers" query (if I count correctly) has little or no chance to be optimizable. If you use the temp table for more that just a one-pass operation, it also makes sense to index relevant fields (using a data-definition query for instance).

So it seems you chose the best path in your case. Good luck with your project!
(°v°)
0
 

Author Comment

by:new_wes
ID: 16994721
in this case last night i remembered that one of the layers was a 'crosstab', and in hindsight building anything on top of that was probably not wise.  given your advice, i'll assume that might be best place to add a 'make-table' layer, then work from there.

thanks for the info - always like to learn!  


0
 
LVL 58

Expert Comment

by:harfang
ID: 16996065
Yes, that is the best place. A crosstab as such can be an optimized query, but anything based on it will not be. The Engine will have to create the table in memory anyway... Then again, the resulting table will not be normalized anymore, hence with very limited query potential.

I normally set things up so that the cross-tab is the very last stage. Not to mention the fact that your sample data does not seem to require a cross-tab anywhere as previous layer. In fact, it looks as though you should actually use the raw tables as source, not any prior query. That a general advice, btw. Try as often as possible to create new queries based on the source. This is both for efficiency and maintenance reasons.

(°v°)
0

Featured Post

Restore individual SQL databases with ease

Veeam Explorer for Microsoft SQL Server delivers an easy-to-use, wizard-driven interface for restoring your databases from a backup. No expert SQL background required. Web interface provides a complete view of all available SQL databases to simplify the recovery of lost database

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Code that checks the QuickBooks schema table for non-updateable fields and then disables those controls on a form so users don't try to update them.
Sometimes MS breaks things just for fun... In Access 2003, only the maximum allowable SQL string length could cause problems as you built a recordset. Now, when using string data in a WHERE clause, the 'identifier' maximum is 128 characters. So, …
In Microsoft Access, learn different ways of passing a string value within a string argument. Also learn what a “Type Mis-match” error is about.
With Microsoft Access, learn how to specify relationships between tables and set various options on the relationship. Add the tables: Create the relationship: Decide if you’re going to set referential integrity: Decide if you want cascade upda…
Suggested Courses

831 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question