473,386 Members | 1,873 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes and contribute your articles to a community of 473,386 developers and data experts.

Ranking Queries in MS Access SQL

Rabbit
12,516 Expert Mod 8TB
Introduction
A query to rank or number the results is often requested. In more powerful database management systems such as Microsoft SQL and DB2, there are often functions to do this. However, in Microsoft Access, no such function exists.

Options
In Access, there are several workarounds:
  1. A running sum in a report
  2. VBA code called in the SELECT clause
  3. A subquery in the SELECT clause
  4. A DCount in the SELECT clause
  5. Joining the table to itself and using a COUNT

Option 1 is probably the easiest if you want to number the rows consecutively but is the least flexible of the options.

Options 2, 3, and 4 require each row to be evaluated separately and can be slow for large data sets.

Option 5 is the most complicated to understand but can often be the most efficient. That is the option I will be discussing in this article.

Examples
Given the following table and data:
Expand|Select|Wrap|Line Numbers
  1. ID Salesperson Division    NumberSold
  2. 1  Robert      Electronics 99
  3. 2  Jenny       Electronics 54
  4. 3  Billy       Appliances  54
  5. 4  Karen       Appliances  102
  6. 5  Kim         Appliances  30
For the first example, let's say you want to rank all the salespeople by number of items sold, you can join the table to itself on the number sold and do a count.

Query
Expand|Select|Wrap|Line Numbers
  1. SELECT 
  2.    t1.Salesperson,
  3.    t1.Division,
  4.    t1.NumberSold,
  5.    COUNT(*) + 1 AS Rank
  6. FROM
  7.    tblSales AS t1
  8.  
  9.    LEFT JOIN tblSales AS t2
  10.       ON t1.NumberSold < t2.NumberSold
  11. GROUP BY
  12.    t1.Salesperson,
  13.    t1.Division,
  14.    t1.NumberSold
Results
Expand|Select|Wrap|Line Numbers
  1. Salesperson Division    NumberSold Rank
  2. Robert      Electronics 99         2
  3. Jenny       Electronics 54         3
  4. Billy       Appliances  54         3
  5. Karen       Appliances  102        1
  6. Kim         Appliances  30         5
Note that this gives ties the same rank. If what you want is to number the rows rather than rank them, you will need to use a unique field.

Query
Expand|Select|Wrap|Line Numbers
  1. SELECT 
  2.    t1.Salesperson,
  3.    t1.Division,
  4.    t1.NumberSold,
  5.    COUNT(*) AS Rank
  6. FROM
  7.    tblSales AS t1
  8.  
  9.    LEFT JOIN tblSales AS t2
  10.       ON t1.NumberSold < t2.NumberSold OR
  11.          (t1.NumberSold = t2.NumberSold AND
  12.          t1.ID <= t2.ID)
  13. GROUP BY
  14.    t1.Salesperson,
  15.    t1.Division,
  16.    t1.NumberSold
Results
Expand|Select|Wrap|Line Numbers
  1. Salesperson Division    NumberSold Rank
  2. Robert      Electronics 99         2
  3. Jenny       Electronics 54         4
  4. Billy       Appliances  54         3
  5. Karen       Appliances  102        1
  6. Kim         Appliances  30         5
If you want to break out the rankings or numbering by grouping field(s), you can do that by including them in the JOIN clause.

Query
Expand|Select|Wrap|Line Numbers
  1. SELECT 
  2.    t1.Salesperson,
  3.    t1.Division,
  4.    t1.NumberSold,
  5.    COUNT(*) AS Rank
  6. FROM
  7.    tblSales AS t1
  8.  
  9.    LEFT JOIN tblSales AS t2
  10.       ON t1.Division = t2.Division AND
  11.          t1.NumberSold <= t2.NumberSold
  12. GROUP BY
  13.    t1.Salesperson,
  14.    t1.Division,
  15.    t1.NumberSold
Results
Expand|Select|Wrap|Line Numbers
  1. Salesperson Division    NumberSold Rank
  2. Robert      Electronics 99         1
  3. Jenny       Electronics 54         2
  4. Billy       Appliances  54         2
  5. Karen       Appliances  102        1
  6. Kim         Appliances  30         3
Note that this ranks from highest to lowest. Going from lowest to highest merely requires flipping the less than operator to a greater than operator.
Feb 9 '14 #1
14 45894
NeoPa
32,556 Expert Mod 16PB
Where's the Like button when you need it :-)
Feb 9 '14 #2
any checked if the samples are correct?
I created the same table and ran the same queries but it seems to be incorrect.
Dec 5 '14 #3
This code worked for me that what was stated above:
Expand|Select|Wrap|Line Numbers
  1. SELECT Salesperson,Division,NumberSold,
  2.        (SELECT COUNT(T1.NumberSold)
  3.           FROM
  4.                  [Table1] AS T1
  5.          WHERE T1.NumberSold >= T2.NumberSold and T1.Division = T2.Division) AS Rank
  6. FROM
  7.       [Table1] AS T2
  8. ORDER BY NumberSold DESC
Dec 5 '14 #4
Rabbit
12,516 Expert Mod 8TB
Thanks for pointing that out. Forgot that the equal sign was needed for the first and last example and a missing condition in the second example. They have now been fixed.

You should be careful with subquery rankings though. With large numbers of records, they can be very slow.
Dec 5 '14 #5
xlDude
3
This might be posting a little late but I found a way that is way way much faster:



SELECT
t1.Salesperson,
t1.Division,
t1.NumberSold,
(SELECT Count(*) As CountS FROM
(SELECT t1.Salesperson, t1.NumberSold
FROM [Table1] t2) As Alias1
WHERE Alias1.Salesperson = t1.Salesperson AND Alias1.NumberSold <= t1.NumberSold) as Rank
FROM Table1 t1
Sep 30 '15 #6
Rabbit
12,516 Expert Mod 8TB
That's not faster. It's an option that is already discussed in the article. What you posted is option 3 in the article. And can be painfully slow for large datasets.
Sep 30 '15 #7
hvsummer
215 128KB
I've created the Extend Vlookup with multi condition in vba excel, I'll thinking about post it like you did here NeoPa lol
Oct 24 '15 #8
NeoPa
32,556 Expert Mod 16PB
My only post in this thread was to say that I liked it HVSummer.

That said, if you feel you have an article in you for such a function then go for it (Article Guidelines).

It would need to be added into the Excel Insights section of course.
Oct 24 '15 #9
hvsummer
215 128KB
can you guy make a like button ? I really want to click on it :D
Oct 25 '15 #10
xlDude
3
That's not faster. It's an option that is already discussed in the article. What you posted is option 3 in the article. And can be painfully slow for large datasets.
It ran in seconds for my dataset of 500K records. The method described in the article was taking over 10 min when I stopped it.
Oct 26 '15 #11
Rabbit
12,516 Expert Mod 8TB
I have not found that to be the case with large datasets unless the joins were set up incorrectly or when indexes are missing.

But of course indexes greatly affect any query and properly creating indexes is an art all on its own. The tables we work with are in the tens of millions to hundreds of millions of rows and our DBAs spend much of their time creating the proper indexes.
Oct 26 '15 #12
xlDude
3
@Rabbit
That's a crazy amount of data lol. I'm limited to MS Access only so maybe that's why the query wouldn't work that well. I'm lucky if I hit 2 million rows of data before splitting the tables up because of the limitations on Access. You guys are in the big leagues.
Oct 26 '15 #13
Rabbit
12,516 Expert Mod 8TB
lol, we certainly deal with a large amount of data. We have a team of people whose entire job is to monitor query performance and create indexes and setting configurations to make them perform better. Most of my time is spent finding the query that works best with how the environment is set up. So there's a lot of back and forth between our 2 teams to maximize performance.

Also, while some of the users have Access front ends, most of the back end data is on SQL Server, which can certainly affect SQL performance.
Oct 26 '15 #14
isladogs
455 Expert Mod 256MB
I realise this is an old thread but came across it in a link provided by Rabbit in this current thread: 30 Records per Report

Firstly, many thanks to Rabbit for the article. I have used the approach described above on many occasions and it works well.
In terms of options 2 & 3, I would like to mention the following:

a) The Serialize function can provide a rank order quickly for both small & large datasets:

Expand|Select|Wrap|Line Numbers
  1. Public Function Serialize(qryname As String, KeyName As String, keyValue) As Long
  2.  
  3. On Error GoTo Err_Handler
  4.  
  5.    'used to create rank order for records in a query
  6.    'add as query field
  7.    'Example Serialize("qry1","field1",[field1])
  8.  
  9.    Dim rst As DAO.Recordset
  10.    Set rst = CurrentDb.OpenRecordset(qryname, dbOpenDynaset, dbReadOnly)
  11.    rst.FindFirst Application.BuildCriteria(KeyName, rst.Fields(KeyName).type, keyValue)
  12.        Serialize = Nz(rst.AbsolutePosition, -1) + 1
  13.     rst.Close
  14.  
  15.    Set rst = Nothing
  16.  
  17. Exit_Handler:
  18.    Exit Function
  19.  
  20. Err_Handler:
  21.    MsgBox "Error " & Err.Number & " in Serialize procedure: " & Err.Description
  22.    GoTo Exit_Handler
  23.  
  24. End Function
I have an article explaining its use together with an example app at Rank Order Queries

b) Allen Browne wrote about the use of subqueries for ranking in this article: Ranking queries in Access. Like any subquery, this method can be slow for large datasets as mentioned in rabbit's article
Jan 30 '21 #15

Sign in to post your reply or Sign up for a free account.

Similar topics

1
by: Joseph Bloch | last post by:
In all the threads on ranking in Access queries, I've not seen anything that deals with ranking against a subset of the query results. What I need to do is take the following query results: Dept...
6
by: onnodb | last post by:
Hi all, While working on an Access UI to a MySQL database (which should be a reasonable, low-cost, flexible interface to the DB, better than web-based, much less costly than a full-fledged .NET...
2
by: Jinx | last post by:
Hi All I am working on a small table of only 15 columns as below: Project Name Individual Staff Name Year of Activity Then 12 Columns for each month having time spent by each individual during...
6
by: chengsi | last post by:
Hi, I have a report which is taking a rather long time to generate because i have had to use nested ranking queries (i'm not sure if nested is the right term - basically rank within rank queries)....
7
by: 663scott | last post by:
Hi I am pretty new to ACCESS. I have created some small databases previously. I need to run a simple query searching for a USERNAME which will gather information from five to ten tables containing...
0
by: zeusspandex | last post by:
Im creating a cross tab query which sorts via and sums the for each type of . I want to be able to add a date criteria, so the user can specify that the query processes data between two dates. ...
1
greeni91
by: greeni91 | last post by:
Hi All, I am creating a database for one of my colleagues and he has asked me to make a query that has a drop down menu and takes into account that the checkboxes on the form have been ticked. ...
10
by: Ben Cherry | last post by:
Hi I have created a tablein acess 07 with three fields; admno, name, and Mark/100. My problem is that i need to have a field with position of this students based on the marks i.e the one with highest...
1
by: Jack z | last post by:
I have a table names Sales with three columns, Dept, Item, Sales. I want to rank sales in ascending order with the rank resetting for each department. I've looked on line but I have not been...
7
by: chip0105 | last post by:
I have five Business Units; BU1, BU2, BU3, BU4, and BU5 is ALL four BU's (scored values are totalled across all BU's). Each Business Unit has the same suppliers with individual monthly score data....
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.