Row_number() returns 空值如何解决这个意想不到的问题

Row_number() returns null value how to solve this unexpected problem

这里是SQL查询

;WITH rankedresults AS 
(
    SELECT 
        userid, 
        rowid 
    FROM   
        (SELECT 
             userid, 
             ROW_NUMBER() OVER (ORDER BY referredplayercount DESC) AS RowId 
         FROM   
             tblusersprofile) dt 
    WHERE  
         rowid BETWEEN 1 AND 50
) 
SELECT 
    tblusersprofile.userid, 
    referredplayercount, 
    username, 
    avatarimagelink, 
    authoritylevel, 
    rowid 
FROM
    tblusersprofile 
LEFT JOIN 
    rankedresults ON tblusersprofile.userid = rankedresults.userid 
WHERE  
    tblusersprofile.userid IN (SELECT rankedresults.userid 
                               FROM rankedresults) 
    AND referredplayercount > 0 
ORDER BY 
    rowid ASC 

此处返回的结果不应为空行号

我想知道 rankedresults 是不是又用这个查询重新生成了?

SELECT rankedresults.userid 
FROM rankedresults

用户 ID 为 1137 仅在 tbluserprofile table 中,而不在 rankedresults CTE 中。

因为是LEFT JOIN,由于没有匹配,结果中的rowid显示为NULL。

row_number() 函数本身不能生成 NULL。

但要确保 CTE 中的 ROW_NUMBER 始终 returns 完全相同的顺序,请在 ORDER BY

中添加用户 ID
ROW_NUMBER() OVER (ORDER BY referredplayercount DESC, userid) AS RowId

但也许您可以避免使用该 CTE 两次?

;WITH rankedresults AS 
(
    SELECT 
     userid, 
     RowId
    FROM
    (
       SELECT 
        userid, 
        ROW_NUMBER() OVER (ORDER BY referredplayercount DESC, userid ASC) AS RowId 
       FROM tblusersprofile
       WHERE referredplayercount > 0 
    ) dt
    WHERE RowId BETWEEN 1 AND 50
) 
SELECT 
    usrprof.userid, 
    usrprof.referredplayercount, 
    usrprof.username, 
    usrprof.avatarimagelink, 
    usrprof.authoritylevel, 
    rr.rowid 
FROM
    tblusersprofile usrprof
JOIN 
    rankedresults rr ON rr.userid = usrprof.userid
ORDER BY 
    rr.RowId ASC

如果您可以使用 OFFSET & FETCH,并且您实际上并不需要 select 中的 RowId?
那么您甚至可能不需要带有 row_number 的 CTE 来分页结果。

declare @offsetrows int = 0;
declare @nextrows int = 50;

SELECT 
 userid, 
 referredplayercount, 
 username, 
 avatarimagelink, 
 authoritylevel
FROM tblusersprofile
WHERE referredplayercount > 0
ORDER BY referredplayercount DESC, userid ASC
OFFSET @offsetrows ROWS FETCH NEXT @nextrows ROWS ONLY;

db<>fiddle here

上的简化测试