我有一個User以 1,000 行命名的 SQL Server 2019 資料庫表,如下所示:

我很難理解這個SELECT帶有OFFSET/ 的查詢FETCH是如何回傳意外結果的:
SELECT *
FROM [User]
WHERE (([NameGiven] LIKE '%1%')
OR ([NameFamily] LIKE '%2%'))
ORDER BY [Id] ASC
OFFSET 200 ROWS FETCH NEXT 100 ROWS ONLY;
查詢結果:

結果范圍從 264 到 452,總共 100 行。為什么201、211等記錄不顯示?我的期望有誤還是查詢條件有誤?
如果我從子句中洗掉OFFSET/FETCH選項ORDER BY,則結果如預期。這讓我認為該WHERE條款不是問題。
任何意見,將不勝感激。
uj5u.com熱心網友回復:
問題是您希望偏移發生在過濾器之前,但實際上它直到過濾器之后才會發生。考慮一個更簡單的示例,您希望所有名為 'sam' 的人都命名為 'sam',而名為 'sam' 的人比您的偏移量還多:
CREATE TABLE dbo.foo(id int, name varchar(32));
INSERT dbo.foo(id, name) VALUES
(1, 'sam'),
(2, 'sam'),
(3, 'bob'),
(4, 'sam'),
(5, 'sam'),
(6, 'sam');
如果你只是說:
SELECT id FROM dbo.foo WHERE name = 'sam';
你得到:
1
2
4
5
6
如果然后添加偏移量 3,
-- this offsets 3 rows _from the filtered result_,
-- not the full table
SELECT id FROM dbo.foo
WHERE name = 'sam'
ORDER BY id
OFFSET 3 ROWS FETCH NEXT 2 ROWS ONLY;
你得到:
5
6
它需要匹配 filter 的所有行,然后跳過這些過濾行中的前三個(1,2,4) - 而不是 1,2,3 就像你的問題暗示你期望的那樣。
- 示例資料庫<>小提琴
回到問題中的案例,您過濾掉了 77 和 89 之類的行,因為它們不包含 1 或 2。所以您要求的偏移量是 200,但就哪些行而言,這意味著偏移量實際上更像是:
200 PLUS the number of rows that *don't* match your filter
until you hit the 200th row that *does*
您可以嘗試強制過濾器在之后發生,例如:
;WITH u AS
(
SELECT *
FROM [User]
ORDER BY [Id]
OFFSET 200 ROWS FETCH NEXT 100 ROWS ONLY
)
SELECT * FROM u
WHERE (([NameGiven] LIKE '%1%')
OR ([NameFamily] LIKE '%2%'))
ORDER BY [Id]; -- yes you still need this one
...但是你幾乎肯定不會在每個頁面中得到 100 行,因為這 100 行中的一些會被過濾器洗掉。我不認為這就是你所追求的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/379319.html
標籤:sql sql-server sql-order-by where子句
