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有作为朋友的用户