Reputation: 391
I would like to ask if there is a way to include the total number of rows, as an additional column, in the returned result sets from a TSQL query using also the Row_Number
command.
For example, getting the results set from a query against Book table in a form similar to this:
RowNum BookId BookTitle TotalRows
--------------------------------------------
1 1056 Title1 5
2 1467 Title2 5
3 121 Title3 5
4 1789 Title4 5
5 789 Title5 5
The query is part of custom paging functionality implemented in a stored procedure. The goal is to return back only the records for the current page Index and limited to the page size, but also the amount of total number of records in the select statement in order to determine the total number of resultset pages.
Upvotes: 25
Views: 49866
Reputation: 402
In SQL Server 2008 and later, add COUNT(*)
OVER ()
as one of the column names in your query and that will be populated with the total rows returned.
It is repeated in every single row but at least the value is available.
The reason why many other solutions do not work is that, for very large result sets, you will not know the total until after iterating all rows which is not practical in many cases (especially sequential processing solutions). This technique gives you the total count after calling the first IDataReader.Read()
, for instance.
select COUNT(*) OVER () as Total_Rows, ... from ...
Upvotes: 27
Reputation: 838876
One can do this with a CTE:
WITH result AS (SELECT ... your query here ...)
SELECT
*,
(SELECT COUNT(*) FROM result) AS TotalRows
FROM result;
In general I'd advise against doing this, but if you really need to then this is how to do it.
Upvotes: 17
Reputation: 34187
Via comments attached to the question it's clear that this question relates to paging. In that scenario, there are two broad approaches:
The first option works well if the total number of rows is measured in the thousands. If the total number is much higher, you best bet is to run the query twice.
This is a typical space/processing trade-off.
Your milage may vary - what works well for one situation may be terrible in another!
Upvotes: 4
Reputation: 41889
Example using the AdventureWorks database
select
*,
TotalVolume = (select COUNT(*) from HumanResources.Department)
from HumanResources.Department
Upvotes: 2
Reputation: 17090
SELECT n ,
COUNT(*) OVER ( PARTITION BY 1 )
FROM ( SELECT 1 AS n
UNION ALL
SELECT 2 AS n
) AS t
Note that @@ROWCOUNT gives you row count from the previous command. Run this:
SELECT 1 AS n;
SELECT n ,
@@ROWCOUNT
FROM ( SELECT 1 AS n
UNION ALL
SELECT 2 AS n
) AS t
Upvotes: 0