使用用戶變量對行號進行編號
我經常在這裏找到答案,建議使用用戶變量對某些事物或其他編號進行編號。也許最清晰的例子是查詢從給定的結果集中選擇第二行。 (這個問題和查詢類似於this answer,但它是this答案,這實際上觸發了這個問題)。使用用戶變量對行號進行保證
SELECT *
FROM (SELECT *, (@row := @row + 1) AS rownum
FROM (SELECT @row := 0) AS init, tablename
ORDER BY tablename.ordercol
) sub
WHERE rownum % 2 = 1
這種方法似乎通常工作。
原因要小心
在另一方面,MySQ docs狀態:
作爲一般規則,你不應該賦值給一個用戶變量和相同的語句中讀出的值。您可能會得到您期望的結果,但這並不能保證。包含用戶變量的表達式的評估順序未定義,並可能根據給定語句中包含的元素進行更改;另外,這個順序不能保證在MySQL服務器的版本之間是相同的。
核心問題
所以我的問題不是如何利用現有的服務器來實現這樣的排序,但使用用戶變量建議的解決方案,而不是是否保證下的所有(合理的)情況和工作所有未來版本的MySQL。
通過「保證」我的意思是像MySQL文檔或一些標準的MySQL聲明符合的權威來源。缺乏這種權威的答案,其他來源如經常使用的教程或MySQL源代碼的一部分可能會被引用。作者「作品」我的意思是,將按順序執行作業,每行結果一次,並按ORDER BY
行所引發的順序執行作業。斷路查詢
的
例子給你舉個例子事情是多麼容易失敗:
SELECT *
FROM (SELECT *, (@row := @row + 1) AS rownum
FROM (SELECT @row := 0) AS init, tablename
HAVING rownum > 0
ORDER BY tablename.ordercol
) sub
WHERE rownum % 2 = 1
將上的MySQL 5.5.27當前安裝在SQL Fiddle產生空的結果。原因似乎是HAVING
條件導致rownum
表達式被評估兩次,所以最終結果將只有偶數。我對幕後發生的事情有了一個想法,並且我並沒有聲稱對HAVING
的詢問很有意義。我只是想證明在工作的代碼和看起來非常相似但中斷的代碼之間有一條細線。
@hvd,感謝[ROW_NUMBER]功能請求中的[pointer](http://bugs.mysql.com/bug.php?id=35893)。 [Dems](http://stackoverflow.com/users/53341/dems)最近[告訴我](http://stackoverflow.com/a/12727443)關於這個功能。似乎相當強大,並明確啓動。太糟糕了,自2008年以來似乎沒有什麼進展。 – MvG
當我看到'ROW_NUMBER'已在您的早期問題的評論和答案中提及時,我刪除了我的評論:) – hvd
[您是否已閱讀此文章?]( http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/)特別是'MySQL不會評估包含用戶變量的表達式,直到它們被髮送到客戶端, 「# –