Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server递归CTE和分页_Sql Server_Select_Paging_Common Table Expression - Fatal编程技术网

Sql server SQL Server递归CTE和分页

Sql server SQL Server递归CTE和分页,sql-server,select,paging,common-table-expression,Sql Server,Select,Paging,Common Table Expression,我有这张桌子 CREATE TABLE [dbo].[friend_blocked_list]( [subdomain] [varchar](50) NOT NULL, [un] [nvarchar](50) NOT NULL, [friend] [nvarchar](50) NOT NULL, [is_blocked] [bit] NOT NULL, [approved] [bit] NOT NULL) 在这里,我使用下面的查询从中选择数据。选择查询将添加用户为好友的用户和按用户

我有这张桌子

 CREATE TABLE [dbo].[friend_blocked_list](
 [subdomain] [varchar](50) NOT NULL,
 [un] [nvarchar](50) NOT NULL,
 [friend] [nvarchar](50) NOT NULL,
 [is_blocked] [bit] NOT NULL,
 [approved] [bit] NOT NULL)
在这里,我使用下面的查询从中选择数据。选择查询将添加用户为好友的用户和按用户添加为好友的用户组合在一起

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 un=@un and subdomain=@subdomain and approved=1 and is_blocked=0

  UNION ALL

  SELECT un as friend
  FROM friend_blocked_list
  WHERE friend=@un and subdomain=@subdomain and approved=1 and is_blocked=0
)
select friend from FRIENDS group by FRIENDS.friend order by FRIENDS.friend asc
它可以处理少量数据,但我希望能够在服务器端进行分页,以减少负载。我正在尝试将它与下面的分页sp结合起来

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 subdomain=@subdomain AND un=@un 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 subdomain=@subdomain AND un=@un AND approved=1 AND is_blocked=0
   )
   SELECT *
   FROM MyTopics
   WHERE RowNumber BETWEEN @FirstRow AND @LastRow
   ORDER BY RowNumber ASC;
end
但和往常一样,我遇到了麻烦:。主要问题是我的查询中的联合。它阻止我在上面使用行数


有什么想法吗?

将行号应用于要返回的列表:

WITH FRIENDS as
(
SELECT friend
  FROM friend_blocked_list
  WHERE un=@un and subdomain=@subdomain and approved=1 and is_blocked=0
UNION ALL
SELECT un as friend
  FROM friend_blocked_list
  WHERE friend=@un and subdomain=@subdomain 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;

以下是已更新的分页过程:

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
如果可以提供FRIEND_BLOCKED_LIST表的更多信息,则可以将查询更改为使用一个CTE。使用相同WHERE子句合并两个查询,同时区分两列,这让我想知道它是否可以写得更好。《老友记》能否改写为:

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

,递归_friends作为选择朋友,按friend asc排序的行数作为FRIENDS的RNFriends似乎不正确您需要在friend\u BLOCKED\u列表表上提供什么类型的信息?同样在联合后的第二个选择中,它应该是其中的t.friend=@un istead of WHERE t.un=@un,所以它们不是相同的Queries列列表,如果不是很长,你对朋友名单上的联盟的逻辑是什么。按原样查询似乎会为同一个人返回FRIEND_BLOCKED_LIST.FRIEND和FRIEND_BLOCKED_LIST.un。不清楚表中发生了什么。修复了联盟的第二部分,很抱歉我的输入错误。我正在尝试选择说usera有作为朋友的用户和说usera有作为朋友的用户