2009-07-17 109 views
1

我有一個基本的MySQL表,方面,由一個 ID長期領域。引用一個MySQL子選擇在另一個查詢

我想創建一個按字母順序排序的字典索引(字面意義上),它將列出選定字詞上方的10個10個字詞,並在下方列出20個字詞。在這裏可以找到一個例子http://www.urbandictionary.com/define.php?term=GD2&defid=3561357在左欄中您可以看到突出顯示的當前術語,以及其上方的一些術語以及下方的一些術語,所有術語均按字母順序排序。我們都知道,MySQL不支持ROW_NUMBER()或類似的函數,所以我們最終會訴諸用戶變量和子選擇。我也不能用用戶定義的變量創建視圖,因爲MySQL不允許這樣做。這是我設法想出(和它的作品):

 SET @row_num := 0; 

     SELECT 
      @term_index := ordered.row_number 
     FROM 
     (
      SELECT 
       @row_num := @row_num + 1 AS row_number, terms.* 
      FROM 
       terms 
      ORDER BY 
       term ASC 
     ) AS ordered 
     WHERE 
      ordered.term = 'example term'; 

     SET @row_num := 0; 

     SELECT * 
     FROM 
     (
      SELECT 
       @row_num := @row_num + 1 AS row_number, terms.* 
      FROM 
       terms 
      ORDER BY 
       term ASC 
     ) AS ordered 
     WHERE 
      row_number BETWEEN @term_index - 10 AND @term_index + 20 

第一個SELECT只是找出整個字母順序排序項表我們的目標項的行號。第二個SELECT使用該信息來獲得10個以上的項目和20個項目以下的信息。

我不知道是否有辦法避免在第二個SELECT查詢中運行子選擇,而只是引用第一個別名爲的訂單。有沒有一個更有效的方式來完成這個,而不必訴諸手動創建一個臨時表?我在這裏做錯了什麼?

回答

1

更新:

看到這篇文章在我的博客的性能細節:


如果您term被索引,你可以運行:

SELECT * 
FROM (
     SELECT * 
     FROM terms 
     WHERE term <= @myterm 
     ORDER BY 
       term DESC 
     LIMIT 10 
     ) q 
UNION ALL 
SELECT * 
FROM (
     SELECT * 
     FROM terms 
     WHERE term > @myterm 
     ORDER BY 
       term 
     LIMIT 20 
     ) q 
ORDER BY 
     term 

,這樣會更有效率。

+0

這確實可行,對我而言更簡單快捷。但是,這兩個子查詢都需要按照MySQL進行別名化處理,並且需要按照ASC順序對第一個子查詢進行排序才能使其工作。非常感謝。 – Salaryman 2009-07-17 18:08:11