我有一个搜索屏幕,用户有5个过滤器可供搜索
我根据这些过滤器值构建了一个动态查询,并一次构建了第10页结果
这在SQL2012中使用OFFSET
和FETCH
工作正常,但我使用 两个 查询来执行此操作。
我想显示10个结果和显示查询找到的总行数(假设为1000)。
目前我通过运行查询 两次 来执行此操作 - 一次用于总计数,然后再次用于分页10行。
有没有更有效的方法来做到这一点?
答案 0 :(得分:23)
您不必运行两次查询。
SELECT ..., total_count = COUNT(*) OVER()
FROM ...
ORDER BY ...
OFFSET 120 ROWS
FETCH NEXT 10 ROWS ONLY;
基于the chat,您的问题似乎有点复杂 - 除了分页之外,您还在DISTINCT
应用了结果。这可能会使确切地确定COUNT()
应该是什么样子以及它应该去哪里变得复杂。这是一种方式(我只是想证明这一点,而不是试图将这种技术融入你聊天中更复杂的查询中):
USE tempdb;
GO
CREATE TABLE dbo.PagingSample(id INT,name SYSNAME);
-- insert 20 rows, 10 x 2 duplicates
INSERT dbo.PagingSample SELECT TOP (10) [object_id], name FROM sys.all_columns;
INSERT dbo.PagingSample SELECT TOP (10) [object_id], name FROM sys.all_columns;
SELECT COUNT(*) FROM dbo.PagingSample; -- 20
SELECT COUNT(*) FROM (SELECT DISTINCT id, name FROM dbo.PagingSample) AS x; -- 10
SELECT DISTINCT id, name FROM dbo.PagingSample; -- 10 rows
SELECT DISTINCT id, name, COUNT(*) OVER() -- 20 (DISTINCT is not computed yet)
FROM dbo.PagingSample
ORDER BY id, name
OFFSET (0) ROWS FETCH NEXT (5) ROWS ONLY; -- 5 rows
-- this returns 5 rows but shows the pre- and post-distinct counts:
SELECT PostDistinctCount = COUNT(*) OVER() -- 10,
PreDistinctCount -- 20,
id, name
FROM
(
SELECT DISTINCT id, name, PreDistinctCount = COUNT(*) OVER()
FROM dbo.PagingSample
-- INNER JOIN ...
) AS x
ORDER BY id, name
OFFSET (0) ROWS FETCH NEXT (5) ROWS ONLY;
清理:
DROP TABLE dbo.PagingSample;
GO
答案 1 :(得分:3)
你可以尝试这样的事吗
SELECT TOP 10 * FROM
(
SELECT COUNT(*) OVER() TOTALCNT, T.*
FROM TABLE1 T
WHERE col1 = 'somefilter'
) v
或
SELECT * FROM
(
SELECT COUNT(*) OVER() TOTALCNT, T.*
FROM TABLE1 T
WHERE col1 = 'somefilter'
) v
ORDER BY COL1
OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY
现在您的totalcnt列中有总计数,您可以使用此列显示总行数
答案 2 :(得分:2)
我的解决方案类似于“rs.answer”
DECLARE @PageNumber AS INT, @RowspPage AS INT
SET @PageNumber = 2
SET @RowspPage = 5
SELECT COUNT(*) OVER() totalrow_count,*
FROM databasename
where columnname like '%abc%'
ORDER BY columnname
OFFSET ((@PageNumber - 1) * @RowspPage) ROWS
FETCH NEXT @RowspPage ROWS ONLY;
返回结果将包括totalrow_count作为第一列名称
答案 3 :(得分:1)
我希望我不会迟到这个问题,但今晚我遇到了一个非常类似的问题。我有一个分页类过度膨胀返回的结果数,因为前一个开发人员正在删除DISTINCT并只是执行表连接的SELECT计数(*)。虽然这不能解决2查询问题,但我最终使用了嵌套查询,因此它看起来像这样:
原始查询
SELECT DISTINCT
field1, field2
FROM
table1 t1
left join table2 t2 on t2.id = t1.id
过度膨胀的结果查询
SELECT
count(*)
FROM
table1 t1
left join table2 t2 on t2.id = t1.id
我的结果查询解决方案
SELECT
count(*)
FROM
(SELECT DISTINCT
field1, field2
FROM
table1 t1
left join table2 t2 on t2.id = t1.id) as tbl;
答案 4 :(得分:1)
在我使用复杂连接和返回约 6,000 条记录的测试中,执行两个单独的查询要快得多。更快,以毫秒为单位获得总数并分别带回 100 条记录的子集,而进行组合查询则需要 17 秒。还有其他人看到这种性能下降吗?显然,它可能与数据结构有关,但这仍然是一个巨大的差异。