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
上的简化测试
这里是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
中添加用户 IDROW_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
上的简化测试