views:

65

answers:

2

Hi folks,

I've been using the following code, given to me by HansUp (cheers!), and it's been working great:

SELECT g.ID, Count(t.Grade) AS Total
FROM grade AS g 
LEFT JOIN (SELECT Grade FROM telephony WHERE [Date] BETWEEN #08/16/2010# AND #08/20/2010#) AS t ON g.ID=t.Grade 
GROUP BY g.ID 
ORDER BY 2 DESC; 

I'm now looking to find the TOP 5 results returned. I thought it would be as simple as:

SELECT **TOP 5** g.ID, Count(t.Grade) AS Total
FROM grade AS g 
LEFT JOIN (SELECT Grade FROM telephony WHERE [Date] BETWEEN #08/16/2010# AND #08/20/2010#) AS t ON g.ID=t.Grade 
GROUP BY g.ID 
ORDER BY 2 DESC; 

Unfortunately that's not working.

Does anyone have any ideas.

Thanks

A: 

This should work.

SELECT TOP 5 g.ID, Count(t.Grade) AS Total
FROM grade AS g 
LEFT JOIN (SELECT Grade FROM telephony WHERE [Date] BETWEEN #08/16/2010# AND #08/20/2010#) AS t ON g.ID=t.Grade 
GROUP BY g.ID 
ORDER BY 2 DESC
Vash
Hey, I get the error The SELECT statement includes a reserved word or an arguement name that is misspelled or missing, or the punctuation is incorrect.
Richard L
@Richard, i've corrected the syntax is **SELECT TOP n** with out (), do you get some other error while you run this query ?
Vash
Vash, thanks for the reply. I've tried this and the query does run, unfortunately it doesnt return only 5 results, it returns them all. Cheers for your help
Richard L
+1  A: 

The TOP clause will get you the top based on your first sort field. Since your first sort field is a constant (2) for all records, you get all records. Add the ID field to your ORDER BY clause and you'll only get five records.

SELECT TOP 5 g.ID, Count(t.Grade) AS Total
FROM grade AS g LEFT JOIN (SELECT Grade FROM telephony WHERE [Date] BETWEEN #08/16/2010# AND #08/20/2010#)  AS t ON g.ID = t.Grade
GROUP BY g.ID
ORDER BY g.ID, 2 DESC;

If you're actually after the top 5 by Total in descending order, change the SQL to the following:

SELECT TOP 5 g.ID, Count(t.Grade) AS Total
FROM grade AS g LEFT JOIN (SELECT Grade FROM telephony WHERE [Date] BETWEEN #08/16/2010# AND #08/20/2010#)  AS t ON g.ID = t.Grade
GROUP BY g.ID
ORDER BY Count(t.Grade) DESC , 2 DESC;

This is top by value, so if multiple records have a total that is the same and it happens to be in the top 5 value of Total, you'll get them all back. If you truly only ever want five records back, you have to sort on a field that is unique.

Forester93
Awesome, thank you very much. One final question tho. How can I use DISTINCT and TOP 5 in the query above? Thanks
Richard L
@Richard L - What's your aim with including a DISTINCT keyword?
Forester93
I have a table with duplicate entries which correspond to another table. I.e if Grade A or Grade B are chosen they fall into the Grade Category 1 so in the grade category table it looks like this: ID | GradeID | Name1 1 Category 1 2 1 Category 1 3 2 Category 2 By not using distinct, the grades are counted for each instance of the grade category. Im trying to only count them once. Thanks
Richard L
@Richard L - I'm not seeing this Grade Category table in your question. Are you trying to relate the results of the SQL above to this table somehow? Please elaborate.
Forester93