2009-07-17 4 views
1

でMySQLのサブ選択を参照します。は私が<i> ID</i>と<i>用語</i>フィールドで構成される基本的なMySQLのテーブル、<i>用語</i>を、持っている別のクエリ

アルファベット順にソートされた辞書インデックス(リテラルの意味で)を作成し、選択した用語の上に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は、単に全体のアルファベット順にソート条件テーブル間で、当社のターゲット用語の行番号を探し出します。 2番目のSELECTは、その情報を使用してその上に10語、下に20語を取得します。

サブセレクトを2番目の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

+0

@サラリーマン:右、固定。 – Quassnoi

+1

@サラリーマン:最初のサブクエリは 'DESC'である必要がありますか?それは与えられたものと等しくない* last * '10 'の値を選択すべきです。 – Quassnoi

関連する問題

 関連する問題