我有这张桌子
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
但一如既往,我遇到了麻烦:)。主要问题是我的查询中的UNION ALL
。它阻止我使用ROW_NUMBER() OVER
。
有什么想法吗?
答案 0 :(得分: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
如果您可以在FRIEND_BLOCKED_LIST
表上提供更多信息,则可以更改查询以使用一个CTE。两个查询具有相同UNION
子句的WHERE
,同时区分两列,这让我想知道它是否能够更好地编写。 FRIENDS CTE可以改写为:
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
答案 1 :(得分:0)
将行号应用于您要返回的列表:
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;