2009-09-06 20 views
0

。選択クエリは、友人として、ユーザーを追加したユーザーとそれはデータの小さなamoutをして正常に動作しますSQL Serverの再帰CTEとページング

declare @un varchar(50), @subdomain varchar(50) 

set @un='user2'; 
set @subdomain ='test.domain.com'; 

WITH FRIENDS as 
(
    SELECT friend 
    FROM friend_blocked_list 
    WHERE [email protected] and [email protected] and approved=1 and is_blocked=0 

    UNION ALL 

    SELECT un as friend 
    FROM friend_blocked_list 
    WHERE [email protected] and [email protected] and approved=1 and is_blocked=0 
) 
select friend from FRIENDS group by FRIENDS.friend order by FRIENDS.friend asc 

ユーザーが友人として追加されているユーザーを組み合わせたが、私は順番にサーバ側でページングを行うことができるようにしたいです負荷を軽減する。 :)私は

create PROCEDURE [dbo].[Paging] 
    @subdomain varchar(50), 
    @un varchar(50), 
    @PageNumber int, 
    @PageSize int 
AS 
BEGIN 
    --paging 
    DECLARE @FirstRow INT,@LastRow INT,@RowCount INT,@PageCount INT 

    --find recordcount and pages 
    SELECT @RowCount = COUNT(*), @PageCount = COUNT(*)/@PageSize 
    FROM friend_blocked_list 
    WHERE [email protected] AND [email protected] AND approved=1 AND is_blocked=0; 

    --- calculate pages  
    IF @RowCount % @PageSize != 0 SET @PageCount = @PageCount + 1 
    IF @PageNumber < 1 SET @PageNumber = 1 
    IF @PageNumber > @PageCount SET @PageNumber = @PageCount 

    SELECT 
     CurrentPage = @PageNumber, 
     TotalPages = @PageCount, 
     TotalRows = @RowCount 

    -- mora calculation 
    SELECT @FirstRow = (@PageNumber - 1) * @PageSize + 1, 
      @LastRow = (@PageNumber - 1) * @PageSize + @PageSize ; 

    WITH MyTopics AS 
    (
     SELECT *, ROW_NUMBER() OVER (order by un asc) AS RowNumber 
     FROM friend_blocked_list 
     WHERE [email protected] AND [email protected] AND approved=1 AND is_blocked=0 
    ) 
    SELECT * 
    FROM MyTopics 
    WHERE RowNumber BETWEEN @FirstRow AND @LastRow 
    ORDER BY RowNumber ASC; 
end 

以下の私のページングSPとそれを組み合わせるしようとしています。しかしいつものように、私は問題を抱えています。主な問題は、クエリ内にUNION ALLです。それはROW_NUMBER() OVERを使用して私を防ぐ。

アイデア?

答えて

1

はここでページング用に更新あなたの手順です:

CREATE PROCEDURE [dbo].[Paging] 
    @subdomain varchar(50), 
    @un varchar(50), 
    @PageNumber int, 
    @PageSize int 
AS 

    DECLARE @start_row int 
    DECLARE @end_row int 

    SET @end_row = @PageNumber * @PageSize 
    SET @start_row = @end_row - (@PageSize - 1) 

BEGIN 

    WITH FRIENDS AS (
    SELECT t.friend 
     FROM FRIEND_BLOCKED_LIST t 
    WHERE t.un = @un 
     AND t.subdomain = @subdomain 
     AND t.approved = 1 
     AND t.is_blocked = 0 
    UNION ALL 
    SELECT t.un as friend 
     FROM FRIEND_BLOCKED_LIST t 
    WHERE t.friend = @un 
     AND t.subdomain = @subdomain 
     AND t.approved = 1 
     AND t.is_blocked = 0) 
SELECT t.friend 
    FROM (SELECT f.friend, 
       ROW_NUMBER() OVER (ORDER BY f.friend) AS rownum 
      FROM FRIENDS f 
     GROUP BY f.friend) t 
WHERE t.rownum BETWEEN @start_row AND @end_row 

END 

あれば1つのCTEを使用するようにクエリを変更することは可能かもしれませんFRIEND_BLOCKED_LISTテーブルに関する詳細情報を提供することができます。同じWHERE句を持つ2つのクエリのUNIONは、2つの列を区別すると、より良い書き込めないかどうか疑問に思う。 CTEのように書き換えることFRIENDSでした:

SELECT COALESCE(t.un, t.friend) as friend 
    FROM FRIEND_BLOCKED_LIST t 
WHERE @un = COALESCE(t.un, t.friend) 
    AND t.subdomain = @subdomain 
    AND t.approved = 1 
    AND t.is_blocked = 0 
+0

右ではないようですFRIEND_BLOCKED_LISTテーブルにありますか? – nLL

+0

は、第二に、すべてのそれがあるべき労働組合の後に選択 t.friend = @un isteadの WHERE t.un = @un それがひどく長くはありませんので、もしそれらが同一クエリが – nLL

+0

列のリストではありません、あなたのロジックはFRIEND_BLOCKED_LISTのUNIONのためのものです。同じ質問の場合は、同じ人物(?)に対してFRIEND_BLOCKED_LIST.friendとFRIEND_BLOCKED_LIST.unが返されるように見えます。テーブルで何が起こっているのかははっきりしない。 –

0

はあなたが戻りたいリストに行番号を適用します。

WITH FRIENDS as 
(
SELECT friend 
    FROM friend_blocked_list 
    WHERE [email protected] and [email protected] and approved=1 and is_blocked=0 
UNION ALL 
SELECT un as friend 
    FROM friend_blocked_list 
    WHERE [email protected] and [email protected] and approved=1 and is_blocked=0) 
, recursive_friends as (
select friend 
, row_number() over (order by friend asc) as rn 
from FRIENDS) 
select friend 
    from recursive_friends 
    where rn between @firstRow and @lastRow 
    order by FRIENDS.friend asc; 
+0

、recursive_friendsは(rnfrom FRIENDSとして)友達ASCによって順序(上の友人、ROW_NUMBER()を選択)とすることで、必要となる情報のどのような – nLL