views:

153

answers:

2

I have basically the same problem outlined in this question, however I am using Microsoft Access as a database instead of MySQL. The result of which is that SQL_CALC_FOUND_ROWS doesn't seem to be available to me. Believe me, I want to switch, but for the moment it is out of the question.

I have a query that aggregates a number of rows, essentially looking for repeat rows based on certain keys, using a group by. It looks something like this:

Select key1, key2, key3, Count(id) 
from table 
group by key1, key2, key3 
having Count(id) > 1

I need to determine the number of rows (or groupings) that query will return.

The database is being accessed through Java, so in theory I could simply run the query, and cycle through it twice, but I was hoping for something faster and preferably SQL based. Any ideas?

+2  A: 

MS Access's record count should give you what you need, or am I missing something?

If you need distinct values from keys, try this

SELECT COUNT(*) AS Expr2
  FROM (
        SELECT DISTINCT [key1] & "-" & [key2] & "-" & [key3] AS Expr1
          FROM Table1
       ) AS SUB;
astander
*The database is being accessed through Java* but I guess Java has an equivalent of RecordCount
Andomar
Can you elaborate? How do I view the Record count? Note, I'm accessing this through Java and not the Access front end...
Daniel Bingham
@Andomar No, it doesn't. There is no way to get the record count out of a Java ResultSet Object.
Daniel Bingham
See edited answer
astander
Awesome, that worked, thank you!
Daniel Bingham
Am glad, am busy working on some access, and havent done it in YEARS!!! X-)
astander
How is this answer not the same as running the query twice?
David-W-Fenton
@David It is running the query twice, but the second time contains only the answer I need. And it runs it in SQL twice. When I said running it twice, I meant running the original query and then scrolling all the way through it's rows (which could be thousands or even millions) twice. Which I would really rather avoid. I'd prefer to let SQL do the counting, since it will likely do it faster than Java will. Which is exactly what this answer does.
Daniel Bingham
A: 

When you create the Statement object, you can declare it to be scrollable. Then the first thing you do is scroll to the end and get the record number. As you're looking at the last record, this will be the number of records in the result set. Then scroll back to the beginning and process normally. Something like:

Statement st=connection.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rs=st.executeQuery(myQueryString);
boolean any=rs.last();
int count = any ? count=getRow()  : 0;
... do whatever with the record count ...
rs.first();
while (rs.next())
{
... whatever processing you want to do ...
}
rs.close();
... etc ...

I have no idea what the performance implications of doing this with MS Access will be, whether it can jump directly to the end of the result set or if it will have to sequentially read all the records. Still, it should be faster than executing the query twice.

Jay
I found this answer in multiple places, however the value returned from getRow was wrong (in the thousands when it should be hundreds). And for some unknown reason - probably some issue with access - scrolling seemed to screw up the cursor.
Daniel Bingham
Hmm. I've used getRow many times with MySQL and Oracle and it's always worked fine. I guess it's possible that there's a bug in MS Access or the JDBC driver. My first thought would be to do the last/getRow and check the count, read some identifying field in that record and dump it out, then do first and loop through the records counting. If last/getRow really says 1000 but looping through only finds 100 or whatever, like wow, that's bizarre. I'd run some tests to make very sure before I concluded there was this blatant a bug.
Jay