我正在每页包含15行的页面上显示数据。我使用SQL Server 2012的OFFSET
和FETCH
关键字限制为我想要的15行。但是,我想显示可用的总行数,如何在单个查询中执行此操作?
例如,在页面顶部,您正在查看1505记录中的15。
是否可以将其与现有查询结合起来?
正如其他人所演示的,您可以做到,但与其使用演示中的COUNT
,不如我要利用系统元数据,这要快得多。从物理上讲,调用SELECT COUNT(1) AS rc FROM MyTable
将迫使存储引擎对可能在内存中或可能不在内存中的所有数据进行枚举,以执行计数并等待所有独占锁被解锁。
您知道什么更有效率吗?只看sys.allocation_units。
SELECT
s.[Name] as [Schema]
, t.[name] as [Table]
, SUM(p.rows) as [RowCount]
FROM
sys.schemas s
LEFT OUTER JOIN
sys.tables t
ON s.schema_id = t.schema_id
LEFT OUTER JOIN
sys.partitions p
ON t.object_id = p.object_id
LEFT OUTER JOIN
sys.allocation_units a
ON p.partition_id = a.container_id
WHERE
p.index_id in(0,1) -- 0 heap table , 1 table with clustered index
AND p.rows is not null
AND a.type = 1 -- row-data only , not LOB
GROUP BY
s.[Name]
, t.[name]
ORDER BY
1
, 2;
h / t致bimonkey以其职位Count the number of rows in every Table in a Database in no time!
如果要执行此操作的“单个”查询,则需要将上述内容与offset和fetch结合使用。
在SQL中,不要将更少的代码行等同于更低的复杂度或更好的性能。
我已经注释了以下查询,因为它确实非常简单。
-- Create variables for our usage
-- http://technet.microsoft.com/en-us/library/ms188927.aspx
DECLARE @OFFSET int = 30
, @FETCH int = 15;
-- Notice the previous statement ends with a semicolon (;)
-- The following structure is a Common Table Expression (CTE)
-- Think of it as a single use View
-- http://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx
WITH COUNTS AS
(
-- This query provides the number of rows in all the tables
-- in the current catalog. It is screaming cheetah wheelies fast
-- as it does not need to physically read each row from each table
-- to generate counts. Instead, it is using system metadata to
-- derive the row count.
-- After the closing ), I will have access to a tabular structure
-- called COUNTS
SELECT
s.[Name] as [Schema]
, t.[name] as [Table]
, SUM(p.rows) as [RowCount]
FROM
-- http://technet.microsoft.com/en-us/library/ms176011.aspx
sys.schemas s
LEFT OUTER JOIN
-- http://technet.microsoft.com/en-us/library/ms187406.aspx
sys.tables t
ON s.schema_id = t.schema_id
LEFT OUTER JOIN
-- http://technet.microsoft.com/en-us/library/ms175012.aspx
sys.partitions p
ON t.object_id = p.object_id
LEFT OUTER JOIN
-- http://technet.microsoft.com/en-us/library/ms189792.aspx
sys.allocation_units a
ON p.partition_id = a.container_id
WHERE
p.index_id in(0,1) -- 0 heap table , 1 table with clustered index
AND p.rows is not null
AND a.type = 1 -- row-data only , not LOB
GROUP BY
s.[Name]
, t.[name]
)
SELECT
T.*
, @OFFSET AS StartingRow
, @FETCH AS PageSize
-- A subquery that uses the CTE above to extract our table's total row count
-- The table and schema below must align with the value in your FROM clause
-- http://technet.microsoft.com/en-us/library/ms189575(v=sql.105).aspx
, (SELECT C.[RowCount] FROM COUNTS C WHERE C.[schema] = 'dbo' AND C.[Table] = 'MyTable') AS TotalRows
FROM
dbo.MyTable T
ORDER BY
1
-- http://technet.microsoft.com/en-us/library/gg699618.aspx
OFFSET 30 ROWS
FETCH NEXT 15 ROWS ONLY;
对于使用SQL Server 10.50的用户,我可以通过公用表表达式(CTE)使用结果集来实现。像这样的东西:
WITH resultSet AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY x.ID DESC) as Row,
x.other_fields
FROM Table x
WHERE conditions_x
),
cte AS
(
SELECT TOP 1 Row AS cte_row FROM resultSet ORDER BY Row DESC
)
-- And finally:
SELECT cte.cte_row AS Total, * FROM resultSet CROSS JOIN cte
WHERE Row BETWEEN 11 AND 20; -- Rows between 11 and 20, for example. Those would be your previously computed START and END row variables.
这应该作为一个查询执行。
虽然我没有在SQL Server 2012中尝试过此方法,但我认为它也可能起作用。
您可以使用COUNT()
:
SELECT COUNT(*) FROM Table
WHERE conditionHere
然后,每页计数必须以您选择的编程语言进行,例如php
或asp.net
。
基本上,计算是这样的:
PageNumber * RecordsPerPage
假设每页15条记录的第2页为:
2 * 15
因此,您的输出将是
30 of NumberOfRecords
您可以使用公式按页数计数
TotalPages = CEILING(TotalRecords / RecordsPerPages)
例如,使用您自己的数字,它将是:
TotalPages = CEILING(1,505 / 15)
如果获得上限,则为101
。
如果为Php
,则可能看起来像这样:
$TotalPages = Ceil($NumberOfRecords / $RecordsPerPages)
如果ASP
使用C#
,则可能看起来像这样:
int TotalPages = Math.Ceil(NumberOfRecords/RecordsPerPages);
但是,如果他们点击了最后一页,那么您可以简单地输入:
TotalRecords of TotalRecords
例如:
1,505 of 1,505