I'd like to get the total count of results and top n rows of some query - is it possible in one statement?
I'd expect the results as:
count(..) column1 column2
125 some_value some_value
125 some_value some_value
Thank you in advance!
You can do this with a
CROSS JOIN
and CTE, but it's not very efficient:I think a better way to get what you want would be to use a single query but multiple result sets, which you can do by using
COMPUTE
:Like this:
Edit: After downvote and COUNT/OVER answer. A comparison on 2 tables of mine
You can see a huge difference between my CROSS JOIN/simple aggregate and a COUNT/empty ORDER BY clause
I've repeated this on a table with 570k rows and here is the IO
what about
Regarding
CROSS JOIN
queriesIn a heavy
INSERT
/DELETE
environment, the cross join will return incorrect row count.Try this from multiple connections
connection 1
connection 2
Each time, the count of records (
@@ROWCOUNT
) is different toT2.cnt
In the case of
COUNT(*) OVER()
, there is only a single table scan and the@@ROWCOUNT
is always the same asT2.cnt
Regarding query plans - SQL 2005 SP3 appears to be much weaker at doing
COUNT(*) OVER()
than SQL 2008 R2. On top of that, it incorrectly reports query costs (I never thought a sub query could cost more than 100% of the entire query).In a lot of scenarios, the cost of the
COUNT(*) OVER()
is between 50-75% of theCROSS JOIN
The best case scenario for a cross join would be if there was a very narrow index to do the count on. That way there will be a clustered index scan for the data + an index scan for the count.
As always, it's best to measure, measure, measure and go with the compromise that you're happy to live with.
give a try for this query: