SQL Server - 沒有Order By子句的分頁

[英]SQL Server - Pagination Without Order By Clause


My situation is that a SQL statement which is not predictable, is given to the program and I need to do pagination on top of it. The final SQL statement would be similar to the following one:

我的情況是,一個不可預測的SQL語句被賦予程序,我需要在它上面進行分頁。最終的SQL語句類似於以下語句:

SELECT * FROM (*Given SQL Statement*) b OFFSET 0 ROWS FETCH NEXT 50 ROWS ONLY;

The problem here is that the *Given SQL Statement" is unpredictable. It may or may not contain order by clause. I am not able to change the query result of this SQL Statement and I need to do pagination on it.

這里的問題是* Given SQL Statement“是不可預測的。它可能包含也可能不包含order by子句。我無法更改此SQL語句的查詢結果,我需要對其進行分頁。

I searched for solution on the Internet, but all of them suggested to use an arbitrary column, like primary key, in order by clause. But it will change the original order.

我在互聯網上搜索了解決方案,但他們都建議按順序使用任意列,如主鍵。但它會改變原來的秩序。

3 个解决方案

#1


2  

The short answer is that it can't be done, or at least can't be done properly.

簡短的回答是它無法完成,或者至少無法正常完成。

The problem is that SQL Server (or any RDBMS) does not and can not guarantee the order of the records returned from a query without an order by clause.
This means that you can't use paging on such queries.
Further more, if you use an order by clause on a column that appears multiple times in your resultset, the order of the result set is still not guaranteed inside groups of values in said column - quick example:

問題是SQL Server(或任何RDBMS)不能也不能保證從沒有order by子句的查詢返回的記錄的順序。這意味着您無法對此類查詢使用分頁。此外,如果對結果集中多次出現的列使用order by子句,則仍無法保證結果集的順序在所述列的值組中 - 快速示例:

;WITH cte (a, b)
AS
(
    SELECT 1, 'a'
    UNION ALL
    SELECT 1, 'b'
    UNION ALL
    SELECT 2, 'a'
    UNION ALL
    SELECT 2, 'b'
)

SELECT *
FROM cte 
ORDER BY a

Both result sets are valid, and you can't know in advance what will you get:

兩個結果集都是有效的,您無法事先知道將獲得什么:

a   b
-----
1   b
1   a
2   b
2   a

a   b
-----
1   a
1   b
2   a
2   b

(and of course, you might get other sorts)

(當然,你可能會得到其他種類)

#2


1  

The problem here is that the *Given SQL Statement" is unpredictable. It may or may not contain order by clause.

這里的問題是* Given SQL Statement“是不可預測的。它可能包含也可能不包含order by子句。

your inner query(unpredictable sql statement) should not contain order by,even if it contains,order is not guaranteed.

您的內部查詢(不可預測的sql語句)不應包含order by,即使它包含,也不保證順序。

To get guaranteed order,you have to order by some column.for the results to be deterministic,the ordered column/columns should be unique

要獲得有保障的訂單,您必須按某些列進行訂購。為了使結果具有確定性,有序列/列應該是唯一的

#3


0  

Please note: what I'm about to suggest is probably horribly inefficient and should really only be used to help you go back to the project leader and tell them that pagination of an unordered query should not be done. Having said that...

請注意:我要提出的建議可能非常低效,並且應該只用於幫助您回到項目負責人並告訴他們不應該對無序查詢進行分頁。話說回來...


From your comments you say you are able to change the SQL statement before it is executed.

根據您的評論,您說您可以在執行之前更改SQL語句。

You could write the results of the original query to a temporary table, adding row count field to be used for subsequent pagination ordering.

您可以將原始查詢的結果寫入臨時表,添加行計數字段以用於后續分頁排序。

Therefore any original ordering is preserved and you can now paginate.

因此,保留任何原始排序,您現在可以分頁。

But of course the reason for needing pagination in the first place is to avoid sending large amounts of data to the client application. Although this does prevent that, you will still be copying data to a temp table which, depending on the row size and count, could be very slow.

但當然,首先需要分頁的原因是避免向客戶端應用程序發送大量數據。雖然這確實可以防止這種情況,但您仍然會將數據復制到臨時表,這取決於行的大小和計數,可能非常慢。

You also have the problem that the page size is coming from the client as part of the SQL statement. Parsing the statement to pick that out could be tricky.

您還遇到了頁面大小來自客戶端作為SQL語句的一部分的問題。解析聲明來解決這個問題可能很棘手。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2017/03/14/9127f95b13e8e08725979b457a65b82.html



 
  © 2014-2022 ITdaan.com 联系我们: