I have a SQL Server 2008 query
SELECT TOP 10 *
FROM T
WHERE ...
ORDER BY ...
I\'d like to get also the total number of the rows. The obious
SELECT TOP (2) *,
(SELECT COUNT(*) AS Expr1 FROM T) AS C
FROM T
Do you want a second query?
SELECT TOP 10
*, foo.bar
FROM
T
CROSS JOIN
(SELECT COUNT(*) AS bar FROM T WHERE ...) foo
WHERE
...
ORDER BY
...
OR
DECLARE @bar int
SELECT @bar = COUNT(*) AS bar FROM T WHERE ...
SELECT TOP 10
*, @bar
FROM
T
CROSS JOIN
(SELECT COUNT(*) AS bar FROM T WHERE ...) foo
WHERE
...
ORDER BY
...
Or (Edit: using WITH)
WITH cTotal AS
(
SELECT COUNT(*) AS bar FROM T WHERE ...)
)
SELECT TOP 10
*, cTotal .bar
FROM
T
WHERE
...
ORDER BY
...
Remove the ORDER BY clause from the 2nd query as well.
No.
SQL Server
doesn't keep COUNT(*)
in metadata like MyISAM
, it calculates it every time.
UPDATE: If you need an estimate, you can use statistics metadata:
SELECT rows
FROM dbo.sysindexes
WHERE name = @primary_key,
where @primary_key
is your table's primary key name.
This will return the COUNT(*)
from last statistics update.
What is in this answer seems to work:
https://stackoverflow.com/a/19125458/16241
Basically you do a:
SELECT top 100 YourColumns, TotalCount = Count(*) Over()
From YourTable
Where SomeValue = 32
TotalCount will have the total number of rows. It is listed on each row though.
When I tested this the query plan showed the table only being hit once.