Random

SQL TOP 語句,如何確保它是“隨機的”?

  • June 15, 2018

我在研究 SQL 時遇到了一個 TOP 語句。IE

SELECT TOP 2 * FROM Persons 

從表 Persons 中最多選擇 2 行。

但是,如果我出於統計原因使用它,我希望這樣的過程是隨機的:即獨立於時間和表格中的順序。

我的問題是:

  1. 如何確保 TOP 語句完全“隨機”(它的選擇沒有排序)?此外,如何確保 TOP 語句針對某些變數(即年齡)進行排序
  2. TOP 語句實際上是如何工作的?

我假設您使用的是 SQL Server,因為這是我所知道的 SQL 版本,TOP而不是LIMIT.

SQL Server 中的數據總是按某種順序排列的。ORDER BY但是,只有在 SQL 語句中包含子句時才能保證該順序是什麼。

如果沒有ORDER BY子句,數據集的順序由生成它所需的過程以及儲存的順序決定。

如果一個表沒有改變,並且您多次對它執行相同的 SQL 語句,您將以相同的順序獲取數據。這是因為查詢引擎每次都應用相同的過程來生成結果數據集。

因此,如果您要對一個表多次發出查詢(沒有插入、更新或刪除),每次都會得到相同的 2 行。

注意:根據表的結構(例如,是否存在聚集索引)和針對錶的活動,您可能會在基本上不是SELECT TOP 2 *靜態的表上給出不同的結果。這就是為什麼您需要 an來保證順序,即使今天沒有 an 的查詢執行會以您想要的順序一致地返回數據。ORDER BY``ORDER BY

使用TOPand ORDER BY,查詢引擎必須至少對您的數據進行部分排序(如果它可以定位並排序前n行,則不必對其餘行進行排序)。使用TOPbut not ORDER BY,它只是選擇它生成的數據集的前n行。

如果你想要一個隨機排序,你(聽起來很奇怪)需要隨機排序數據。ORDER BY NEWID()(正如Lamak評論中所建議的)會這樣做。NEWID()每次執行時都會生成一個新的 GUID,並且這些 GUID 不會以任何順序生成。這個 SO question解釋了它是如何工作的。它還描述瞭如何TOP進一步工作。

正如sp_BlitzErik指出的那樣,ORDER BY NEWID()它並不快,並且表越大越慢(它必須為表中的每一行生成一個 GUID,而不管TOP要返回的行數如何)。他連結到如何從大表中獲取隨機行,這是他公司網站上的一篇文章,以獲取從表中獲取真正隨機行的其他建議。

基本上,這些選項是使用一個相對晦澀的查詢選項,稱為TABLESAMPLE,這可能會出現問題;或者,使用該RAND函式生成隨機 ID 值以返回一行(如果您需要多於一或兩行,或者每次執行時需要可變數量的行,則將隨機數轉儲到臨時表中)。您還可以使用RANDwithOFFSET ... FETCH子句在 SQL 2012 或更高版本中獲取單個隨機行。

引用自:https://dba.stackexchange.com/questions/209770