Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it better / more efficient to use sub queries or SELECT statements within the WHERE clause (in MS Access)

Tags:

sql

ms-access

I have an MS Access database that contains a table of dates, scores and the people to whom those scores relate, e.g.

Date   Score Name
1/6/11     5 Dave
1/6/11    10 Sarah
2/6/11     4 Dave
2/6/11     3 Graham
3/6/11     1 Dan
4/6/11    11 Dan
4/6/11     9 Graham

I would like to write a query to find who got the highest socre on each date, i.e. a result of:

Date   Score Name
1/6/11    10 Sarah
2/6/11     4 Dave
3/6/11     1 Dan
4/6/11    11 Dan

I can think of two solutions to this problem (I am open to alternative suggestions), as follows:

1) Write a query to find the minimum score for each date then a second query joining the first query to the original table. i.e.:

Query1:

SELECT Date, MAX(Score) AS MaxScore FROM ScoresTable GROUP BY Date

Query2:

SELECT ScoresTable.* 
FROM ScoresTable INNER JOIN Query1 
  ON ScoresTable.Date = Query1.Date 
  AND ScoresTable.Score = Query1.MaxScore

[These could be combined as a single query:

SELECT ScoresTable.* 
FROM ScoresTable INNER JOIN 
  (SELECT Date, MAX(Score) AS MaxScore 
  FROM ScoresTable GROUP BY Date) Query1 
  ON ScoresTable.Date = Query1.Date 
  AND ScoresTable.Score = Query1.MaxScore

but I prefer to keep them separate to make it easier for others to follow, i.e. they can use the Access interface without knowing SQL]

2) Write a single query with another simple query within the WHERE clause (this is a new method I have only just read about, does it have a name?), i.e.:

SELECT * FROM ScoresTable WHERE Score = 
  (SELECT MAX(Score) FROM ScoresTable AS st WHERE st.Date = ScoresTable.Date)

The latter is clearly more elegant, but appears to run more slowly. Which is the better option? The datasets can get quite large.

like image 784
jofitz Avatar asked Jun 21 '11 10:06

jofitz


1 Answers

Your single composite query already looks optimal to me, I doubt that you can do simpler or more efficient.
Judicious use of indexes in your table should ensure that the query runs pretty fast.

Your last query is called a Correlated subquery.
It is sometimes useful, but can be very slow: the subquery will need to be executed for each record in the ScoresTable because the result of the subquery depends on the value of each individual record in ScoresTable.
This is rather difficult for the database engine to optimise.

If you are interested in finding out details about how the query planner optimises your queries, have a look at these articles, they'll show you what's under the hood:

  • Use Microsoft Jet's ShowPlan to write more efficient queries
  • Access 2002 Desktop Developer's Handbook, Chapter 15: Application Optimization
like image 67
Renaud Bompuis Avatar answered Nov 02 '22 17:11

Renaud Bompuis