ユーザーが5つのフィルターで検索できる検索画面があります。
これらのフィルター値に基づいて動的クエリを作成し、一度に10ページの結果を取得しました。
これはOFFSET
とFETCH
を使用してSQL2012で正常に機能していますが、twoを使用しています=これを行うクエリ。
10個の結果を表示し、クエリで見つかった行の総数を表示します(たとえば、1000としましょう)。
現在、私はクエリtwiceを実行することでこれを行っています-合計カウントに対して1回、次に10行をページングするためにもう一度。
これを行うためのより効率的な方法はありますか?
クエリを2回実行する必要はありません。
_SELECT ..., total_count = COUNT(*) OVER()
FROM ...
ORDER BY ...
OFFSET 120 ROWS
FETCH NEXT 10 ROWS ONLY;
_
the chat に基づくと、問題は少し複雑になっているようです。ページングに加えて、結果にDISTINCT
を適用しています。これは、COUNT()
がどのように見えるべきか、どこに行くべきかを正確に決定することを複雑にする可能性があります。ここに1つの方法があります(チャットからのはるかに複雑なクエリにこの手法を組み込むのではなく、これをデモンストレーションしたいだけです)。
_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
_
私の解決策は「rs。答え」に似ています
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が含まれます
このようなことを試すことができますか
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列に合計数が表示され、この列を使用して行の総数を表示できます
私がこの質問に飛び込むのに遅すぎないことを願っていますが、今夜は非常によく似た問題に遭遇しました。以前の開発者がDISTINCTを削除し、テーブル結合のSELECT count(*)を実行しただけだったため、返された結果の数を大幅に増やしているページングクラスがありました。これは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;