SELECT [STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY]
[DISTINCT | DISTINCTROW | ALL]
select_expression,...
[INTO {OUTFILE | DUMPFILE} 'file_name' export_options]
[FROM table_references
[WHERE where_definition]
[GROUP BY {unsigned_integer | col_name | formula} [ASC | DESC], ...
[WITH ROLLUP]]
[HAVING where_definition]
[ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...]
[LIMIT [offset,] row_count | row_count OFFSET offset]
[PROCEDURE procedure_name(argument_list)]
[FOR UPDATE | LOCK IN SHARE MODE]]
SELECT は1 つ以上のテーブルからレコードを選択して取り出すときに使用します。
各 select_expression は、取り出すカラムを表します。
SELECT は、どのテーブルも参照することなく、計算によって求められたレコードを取り出すときにも使用できます。
次に例を示します。
mysql> SELECT 1 + 1;
-> 2
使用する節はいずれも、構文の説明で示している順序とまったく同じ順序で記述する必要があります。たとえば、HAVING 節はあらゆる GROUP BY 節の後に、またあらゆる ORDER BY 節の前に配置しなければなりません。
SELECT 式には、AS alias_name を使用してエイリアスを指定することができる。
このエイリアスは式のカラム名として使用されるもので、ORDER BY 節または HAVING 節とともに使用できる。次に例を示す。
mysql> SELECT CONCAT(last_name,', ',first_name) AS full_name
FROM mytable ORDER BY full_name;
SELECT 式のエイリアスの指定時、AS キーワードは省略できる。
前の例は、次のように記述することも可能。
mysql> SELECT CONCAT(last_name,', ',first_name) full_name
FROM mytable ORDER BY full_name;
AS は省略できるため、2 つの SELECT 式の間にカンマを付け忘れると微妙な問題が生じることがある。この場合、2 番目の式は MySQL によってエイリアス名として解釈される。たとえば、次のステートメントで、columnb はエイリアス名とみなされる。
mysql> SELECT columna columnb FROM mytable;
WHERE 節ではカラム名のエイリアスは使用できない。これは、WHERE 節の実行時点でカラム値がまだ判別されないことがあるため。
See 項A.5.4. 「alias の問題」。
FROM table_references 節は、レコードの取り出し元のテーブルを表す。複数のテーブルを指定する場合は、結合操作を実行する。結合構文については、項6.4.1.1. 「JOIN 構文」 を参照。
指定する各テーブルについて、必要に応じて、そのテーブルのエイリアスを指定することができる。
table_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | FORCE INDEX (key_list)]]
MySQL バージョン 3.23.12 以降では、テーブルからのデータの取り出し時に、どのインデックスを使用すべきか MySQL に知らせるためのヒントを指定することができる。これは、EXPLAIN で MySQL が使用可能なインデックスのリストの中から誤ったインデックスを使用していることが明らかになったときに役立つ。USE INDEX (key_list) と指定することによって、使用可能なインデックスの中から特定のインデックスを使ってテーブル内のレコードを検索するよう MySQL に指示できる。もう 1 つの IGNORE INDEX (key_list) 構文は、特定のインデックスを使用しないよう MySQL に指示するときに使用する。
MySQL 4.0.9 では、FORCE INDEX も使用できる。これは USE INDEX (key_list) と同じように動作するが、異なる点として、この構文の場合、テーブルのスキャンは非常にコストがかかるという前提に立つ。つまり、テーブルのスキャンが実行されるのは、どのインデックスを使用してもテーブル内のレコードを検索できない場合に限られる。
USE/IGNORE/FORCE KEY は USE/IGNORE/FORCE INDEX のシノニム。
注意: USE/IGNORE/FORCE INDEX は、MySQL でテーブル内のレコードの検索方法と結合の実行方法を決めるときにどのインデックスを使用するか、という点にのみ影響する。ORDER BY や GROUP BY の解決時にインデックスを使用するかどうかには影響しない。
MySQL 4.0.14 では、MySQL にテーブルのスキャンよりもキーのスキャンを優先させるための代替方法として、SET MAX_SEEKS_FOR_KEY=value も使用できる。
テーブルは(カレントデータベース内のものなら)tbl_name として参照できる。データベースを明示的に指定する場合は、dbname.tbl_name として参照する。
カラムは、col_name、tbl_name.col_name、または db_name.tbl_name.col_name として参照できる。SELECT ステートメントでカラムを参照するときには、その参照があいまいにならない限り、カラム名の前に tbl_name や db_name.tbl_name を付ける必要はない。より明示的なカラム参照形式が必要となるあいまいな例については、項6.1.2. 「データベース名、テーブル名、インデックス名、カラム名、エイリアス名」を参照。
バージョン 4.1.0 以降では、どのテーブルも参照されない状況において、ダミーテーブル名として DUAL を指定することができる。これはもっぱら互換性を考慮した機能である。一部の他のサーバではこの構文が必要となる。
mysql> SELECT 1 + 1 FROM DUAL;
-> 2
テーブル参照には、tbl_name [AS] alias_name を使用してエイリアスを指定することができる。
mysql> SELECT t1.name, t2.salary FROM employee AS t1, info AS t2
-> WHERE t1.name = t2.name;
mysql> SELECT t1.name, t2.salary FROM employee t1, info t2
-> WHERE t1.name = t2.name;
出力用に選択されるカラムは、ORDER BY 節と GROUP BY 節において、カラム名、カラムエイリアス、またはカラム位置を使用して参照することができる。カラム位置は 1 から始まる。
mysql> SELECT college, region, seed FROM tournament
-> ORDER BY region, seed;
mysql> SELECT college, region AS r, seed AS s FROM tournament
-> ORDER BY r, s;
mysql> SELECT college, region, seed FROM tournament
-> ORDER BY 2, 3;
逆の順序でソートするには、ORDER BY 節においてソートキーとするカラムの名前に DESC(降順)キーワードを付ける。
デフォルトは昇順だが、昇順を明示的に指定するには、ASC キーワードを指定する。
WHERE 節では、MySQL でサポートしている任意の機能を使用できるが、例外として集約(集計)機能だけは使用できない。
See 項6.3. 「SELECT 節と WHERE 節で使用する関数」。
HAVING 節では、select_expression で指定した任意のカラムまたはエイリアスを参照することができる。この節は、処理の終わり近くになって(項目がクライアントに送られる直前)、最適化されることなく適用される(LIMIT は HAVING の後に適用)。WHERE 節に組み込むべき項目に対しては、HAVING を使用してはならない。たとえば、次のように記述しないようにする。
mysql> SELECT col_name FROM tbl_name HAVING col_name > 0;
正しくは次のように記述する。
mysql> SELECT col_name FROM tbl_name WHERE col_name > 0;
MySQL バージョン 3.22.5 以降では、次のようなクエリも使用できる。
mysql> SELECT user,MAX(salary) FROM users
-> GROUP BY user HAVING MAX(salary)>10;
それより前の MySQL バージョンでは、代わりに次のように記述する。
mysql> SELECT user,MAX(salary) AS sum FROM users
-> group by user HAVING sum>10;
DISTINCT、DISTINCTROW、ALL の各オプションでは、重複レコードを返すかどうかを指定する。デフォルト(ALL)では、マッチするすべてのレコードが返される。DISTINCT と DISTINCTROW はシノニムで、これらを指定した場合、結果セットから重複レコードが削除される。
STRAIGHT_JOIN と HIGH_PRIORITY、および SQL_ で始まる各オプションは、SQL-99 に対する MySQL の拡張。
STRAIGHT_JOIN では、オプティマイザに、FROM 節に指定された順序で強制的にテーブルを結合させることができる。オプティマイザが最適でない順序でテーブルを結合するときには、このオプションを使用することによって、クエリを高速化できる。
See 項5.2.1. 「EXPLAIN 構文(SELECT に関する情報の取得)」。
HIGH_PRIORITY を指定すると、SELECT ステートメントがテーブルを更新するステートメントよりも優先される。このオプションは、非常に迅速に処理され、かつ直ちに実行する必要があるクエリに対してのみ使用するようにする。
SELECT HIGH_PRIORITY クエリは、対象のテーブルが読み取り用にロックされれば、たとえテーブルが解放されるのを待っている更新ステートメントがあっても、実行される。
SQL_BIG_RESULT は、GROUP BY または DISTINCT とともに使用することができ、それによって、結果セットに多くのレコードが組み込まれることをオプティマイザに通知できる。この場合、MySQL で、ディスクベースの一時テーブルが必要に応じて直接使用される。
また、この場合、GROUP BY 要素のキーで一時テーブルを処理するよりソートを行うほうが優先される。
SQL_BUFFER_RESULT では、結果が一時テーブルに強制的に格納される。結果セットをクライアントに送るのに時間がかかる場合には、このオプションを指定することによって、MySQL によるテーブルのロックを早く解放させることができる。
SQL_SMALL_RESULT は MySQL 固有のオプション。このオプションを GROUP BY または DISTINCT とともに使用することで、結果セットが小さいものになることをオプティマイザに通知できる。この場合、ソートを行う代わりに、迅速な一時テーブルを使用して結果のテーブルが格納される。MySQL バージョン 3.23 では、通常、このオプションを使用する必要はない。
SQL_CALC_FOUND_ROWS(バージョン 4.0.0 以降)では、LIMIT 節を無視した場合に結果セットに含まれるすべてのレコード数を計算するよう MySQL に指示できる。
その後、
SELECT FOUND_ROWS() を使用して、計算されたレコード数を取り出せる。
See 項6.3.6.2. 「その他の各種関数」。
注意: 4.1.0 より前のバージョンでは、
LIMIT 0 を指定した場合、このオプションは機能しない。この場合、迅速に戻るよう最適化される(その結果、レコードカウントは 0 になる)。 See 項5.2.9. 「MySQL による LIMIT の最適化」。
SQL_CACHE では、QUERY_CACHE_TYPE=2(DEMAND)を使用した場合に、クエリの結果をクエリキャッシュに格納するよう MySQL に指示できる。
See 項6.9. 「MySQL クエリキャッシュ」。 UNION またはサブクエリを使用したクエリでは、このオプションはクエリのあらゆる SELECT ステートメントで適用される。
SQL_NO_CACHE では、クエリの結果をクエリキャッシュに格納しないよう、MySQL に指示することができる。 See 項6.9. 「MySQL クエリキャッシュ」。
UNION またはサブクエリを使用したクエリでは、このオプションはクエリのあらゆる SELECT ステートメントで適用される。
GROUP BY を使用すると、GROUP BY のすべてのフィールドに対して ORDER BY を使用した場合と同じように、出力レコードが GROUP BY に指定した基準に基づいてソートされる。MySQL では、GROUP BY 節を拡張しており、この節で指定したカラムの後に ASC と DESC のいずれかを指定することができる。
SELECT a,COUNT(b) FROM test_table GROUP BY a DESC
MySQL では、GROUP BY の使用を拡張しており、GROUP BY 節に指定していないフィールドも選択できる。
クエリで期待した結果が得られない場合は、GROUP BY の説明を参照。
See 項6.3.7. 「GROUP BY 節で使用する関数と修飾子」。
MySQL 4.1.1 以降、GROUP BY には WITH ROLLUP 修飾子を使用できる。
See 項6.3.7.2. 「GROUP BY の修飾子」。
LIMIT 節を使用すると、SELECT ステートメントで返されるレコード数を制限することができる。LIMIT は 1 つまたは 2 つの数値引数を取る。これらの引数は整数定数でなければならない。
引数が 1 つの場合、その値は、戻り値として返す、結果セットの冒頭からのレコード数を表す。 引数が 2 つの場合、最初の引数は戻り値として返す最初のレコードまでのオフセットを表し、2 つ目の引数は戻り値として返す最大レコード数を表す。最初のレコードのオフセット値は 0(1 ではない)。
PostgreSQL との互換性を確保するため、MySQL では
LIMIT row_count OFFSET offset 構文もサポートしている。
mysql> SELECT * FROM table LIMIT 5,10; # Retrieve rows 6-15
特定のオフセット位置から結果セットの終わりまでのすべてのレコードを取り出すには、2 つ目のパラメータに大きな数値を指定できる。
mysql> SELECT * FROM table LIMIT 95,18446744073709551615; # Retrieve rows 96-last.
引数が 1 つの場合、その値は戻り値として返す最大レコード数を表す。
mysql> SELECT * FROM table LIMIT 5; # Retrieve first 5 rows
つまり、
LIMIT n は
LIMIT 0,n と指定するのと同じである。
SELECT ... INTO OUTFILE 'file_name' 形式の SELECT では、
SELECT したレコードがファイルに書き込まれる。ファイルはサーバホスト上に作成される。既存のファイルを指定することはできない(この制限は、特に、/etc/passwd などのデータベーステーブルやファイルが破壊されないようにするため)。この形式の SELECT を使用するには、サーバホストに対する FILE 権限が必要となる。
SELECT ... INTO OUTFILE ステートメントの用途は、主に、サーバマシン上のテーブルのダンプをきわめて迅速に実行できるようにすることである。サーバホスト以外のホストに結果のファイルを作成する必要があるときには、
SELECT ... INTO OUTFILE は使用できない。この場合、代わりに、mysqldump --tab や mysql -e "
SELECT ..." > outfile などのクライアントプログラムを使用してファイルを生成する。
SELECT ... INTO OUTFILE は LOAD DATA INFILE の逆。このステートメントの export_options 部分の構文は、LOAD DATA INFILE ステートメントで使用される FIELDS および LINES 節と同じ構成になっている。
See 項6.4.8. 「LOAD DATA INFILE 構文」。
結果のテキストファイルでは、以下の文字だけが ESCAPED BY 指定の文字でエスケープされる。
ESCAPED BY 指定文字自体
FIELDS TERMINATED BY 指定の最初の文字
LINES TERMINATED BY 指定の最初の文字
また、ASCII 0 は、ESCAPED BY の指定文字の後ろに 0(ASCII 48)を付けたものに変換される。
上記の文字をエスケープする理由は、ファイルを確実に読み返せるようにするには、FIELDS TERMINATED BY、ESCAPED BY、LINES TERMINATED BY 指定されている文字をすべてエスケープしなければならないため。ASCII 0 は一部のページャーでの表示を容易化するためにエスケープされる。
結果のファイルは SQL の構文に従う必要はないため、その他のエスケープ処理は必要ない。
次に、多くの古いプログラムで使用されている形式でファイルを生成する例を示す。
SELECT a,b,a+b INTO OUTFILE "/tmp/result.text" FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY "\n" FROM test_table;
INTO OUTFILE の代わりに INTO DUMPFILE を使用すると、MySQL によってファイルに 1 つのレコードだけが書き込まれる。この場合、カラムや行の終了は何も含まれず、エスケープ処理もまったく行われない。これは、ファイルに BLOB 値を格納するときに役立つ。
注意: INTO OUTFILE と INTO DUMPFILE で作成されるファイルは、サーバホスト上にあるアカウントで書き込み可能であるかもしれない。その理由は、MySQL サーバを実行しているアカウントで、それらファイルを作成するからであり、作成されたファイルはそのアカウントがオーナーになっているからである(mysqld は root として実行すべきでない)。
ファイルの内容を操作できるようにするには、ファイルを全ユーザ書き込み可能にする必要がある。
PROCEDURE 節には、結果セット内のデータの処理に使用するプロシージャを指定する。例については、項13.3.1. 「プロシージャの分析」を参照。
ページロックまたは行ロック機能があるストレージエンジンに対して FOR UPDATE を使用すると、現在のトランザクションが終了するまで、検査対象のレコードは書き込みに対してロックされる。















