12

次のような1つのストアドプロシージャで、データのページとすべてのデータの行数を返そうとしています。

WITH Props AS
(
    SELECT *,
    ROW_NUMBER() OVER (ORDER BY PropertyID) AS RowNumber
    FROM Property
    WHERE PropertyType = @PropertyType AND ...
)   

SELECT * FROM Props 
WHERE RowNumber BETWEEN ((@PageNumber - 1) * @PageSize) + 1 AND (@PageNumber * @PageSize);

行数(最大行数)を返すことができません。

私はこれがすでに議論されていることを知っています(私はこれを見ました: row_numberを使用してクエリから@@ rowcountを取得する効率的な方法)が、CTEを追加するCOUNT(x) OVER(PARTITION BY 1)と、パフォーマンスが低下し、通常は時間がかからない上記のクエリは永遠にかかります実行する。行ごとにカウントが計算されるからだと思いますか?CTEを別のクエリで再利用できないようです。テーブルプロップには100kレコードがあり、CTEは5kレコードを返します。

4

3 に答える 3

20

T-SQLでは、次のようになります。

;WITH Props AS
(
    SELECT *,
        ROW_NUMBER() OVER (ORDER BY PropertyID) AS RowNumber
    FROM Property
    WHERE PropertyType = @PropertyType AND ...
)

, Props2 AS
(
    SELECT COUNT(*) CNT FROM Props
)

-- Now you can use even Props2.CNT
SELECT * FROM Props, Props2
WHERE RowNumber BETWEEN ((@PageNumber - 1) * @PageSize) + 1 AND (@PageNumber * @PageSize);

今、あなたはすべてのラインにCNTを持っています...それとも何か違うものが欲しかったのですか?カウントのみの2番目の結果セットが必要ですか?じゃやれ!

-- This could be the second result-set of your query.
SELECT COUNT(*) CNT
FROM Property
WHERE PropertyType = @PropertyType AND ...

注:再編集すると、Davidが参照していたクエリ1はゴミ箱に入れられ、クエリ2はクエリ1になりました。

于 2011-09-15T20:07:21.973 に答える
1

結果セット全体のカウントが必要ですか?

これは迅速に機能しますか?

SELECT *,(select MAX(RowNumber) from Props) as MaxRow 
FROM Props 
WHERE RowNumber BETWEEN ((@PageNumber - 1) * @PageSize) + 1 
    AND (@PageNumber * @PageSize);
于 2011-09-15T19:59:48.350 に答える
1

私は同じ問題を抱えていて、ページと合計行を返すコードを共有したいと思いました。この問題は、一時テーブルによって修正されます。ストアドプロシージャの本体は次のとおりです。

DECLARE @personsPageTable TABLE(
  RowNumber INT, 
  PersonId INT, 
  FirstName NVARCHAR(50), 
  LastName NVARCHAR(50), 
  BirthDate DATE, 
  TotalCount INT);
    
        ;WITH PersonPage AS 
        (
            SELECT 
                 ROW_NUMBER() OVER(ORDER BY persons.Id) RowNumber,
                 Id,
                 FirstName,
                 LastName,
                 BirthDate
            FROM Persons
            WHERE BirthDate >= @BirthDateFrom AND BirthDate <= @BirthDateTo
        ), TotalCount AS( SELECT COUNT(*) AS [Count] FROM PersonPage)
        INSERT INTO @personsPageTable
        SELECT *, (select * from TotalCount) TotalCount FROM PersonPage
        ORDER BY PersonPage.RowNumber ASC
        OFFSET ((@pageNumber - 1) * @pageSize) ROWS
        FETCH NEXT @pageSize ROWS ONLY
    
        SELECT TOP 1 TotalCount FROM @personsPageTable
    
        SELECT 
            PersonId, 
            FirstName, 
            LastName, 
            BirthDate
        FROM @personsPageTable

ご覧のとおり、CTEの結果と合計行を一時テーブルに入れて2つのクエリを選択します。最初のリターンの合計数とデータを含む2番目のリターンページ。

于 2018-11-22T12:55:49.077 に答える