SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr
, ... [FROMtable_references
[WHEREwhere_condition
] [GROUP BY {col_name
|expr
|position
} [ASC | DESC], ... [WITH ROLLUP]] [HAVINGwhere_condition
] [ORDER BY {col_name
|expr
|position
} [ASC | DESC], ...] [LIMIT {[offset
,]row_count
|row_count
OFFSEToffset
}] [PROCEDUREprocedure_name
(argument_list
)] [INTO OUTFILE 'file_name
'export_options
| INTO DUMPFILE 'file_name
' | INTO @var_name
[, @var_name
]] [FOR UPDATE | LOCK IN SHARE MODE]]
SELECT
は、1つまたは複数のテーブルから選択した行を検索するために利用され、UNION
ステートメントとサブクエリを含む事ができます。項12.2.7.2. 「UNION
構文」、項12.2.8. 「サブクエリ構文」
を参照して下さい。
一番良く利用される SELECT
ステートメントの条項はこれらです。
各 select_expr
は、検索したいカラムを指示します。少なくても1つの
select_expr
が必要です。
table_references
はどのテーブルから行の検索をするかを指示します。その構文は
項12.2.7.1. 「JOIN
構文」 で説明されています。
WHERE
条項がもしあれば、それは行が選択される為に満たさなければいけない条件を指示します。
where_condition
は選択される行が真であるかを確認する式です。ステートメントは、もし
WHERE
条項がなければ全ての行を選択します。
WHERE
条項の中では、総計
(要約) 関数以外の、MySQL
がサポートする関数や演算子の全てを利用する事ができます。詳しくは
章 11. 関数と演算子 を参照してください。
SELECT
もまた、別のテーブルへの参照無しで算出された行を検索する為に利用する事ができます。
例:
mysql> SELECT 1 + 1;
-> 2
テーブルが参照されていない場合に、DUAL
をダミー
テーブルとして指定する事が許されています。
mysql> SELECT 1 + 1 FROM DUAL;
-> 2
DUAL
は純粋に、全ての
SELECT
ステートメントが
FROM
と、別の条項を持津事を要求する人々の為に役立つ物です。MySQL
は条項を無視するかもしれません。 MySQL
は、もしテーブルが参照されなければ
FROM DUAL
を要求しません。
通常、利用される条項は構文説明に表されるのと全く同じ順番で与える必要があります。例えば、HAVING
条項は GROUP BY
条項の前、ORDER BY
条項の後に来なければいけません。例外は、INTO
条項が構文の説明どおりに表される事も、FROM
条項の直前に先行して表される事も両方可能であるという事です。
select_expr
に AS
を利用したエイリアスを与える事ができます。そのエイリアスは、式のカラム名として利用され、
alias_name
GROUP BY
、ORDER
BY
、または HAVING
条項内で利用する事ができます。例:
SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;
AS
キーワードは、select_expr
をエイリアスを指定する時には任意です。前出の例はこのように書く事が可能でした。
SELECT CONCAT(last_name,', ',first_name) full_name FROM mytable ORDER BY full_name;
しかし、AS
が任意なので、2つの
select_expr
式の間のカンマを忘れると、わずかなエラーが発生する事があります。MySQL
は2番目をエイリアスだと解釈します。例えば次のステートメントの中で、
columnb
はエイリアスとして扱われています。
SELECT columna columnb FROM mytable;
この理由の為、カラムのエイリアスを指定する時には
AS
を明示的に利用する癖をつけておくと良いでしょう。
WHERE
条項が実行された時にはまだカラム値が決定されていない可能性があるので、WHERE
条項の中でカラムのエイリアスを利用するのは許されていません。
詳しくは 項B.1.5.4. 「Problems with Column Aliases」
を参照してください。
FROM
はどのテーブルから行の検索をするかを指示します。もし複数のテーブルに名前をつけると、それは結合を実行するという事になります。結合構文の情報に関しては、項12.2.7.1. 「table_references
JOIN
構文」
を参照してください。指定された各テーブルにエイリアスを任意で指定する事ができます。
tbl_name
[[AS]alias
] [{USE|IGNORE|FORCE} INDEX (key_list
)]
どのようにインデックスを選択するかについてのオプチマイザ
ヒントを与える USE
INDEX
、IGNORE
INDEX
、FORCE INDEX
の利用については 項12.2.7.1. 「JOIN
構文」
で説明しています。
MySQL がテーブル スキャンの代わりにキー
スキャンを好むように仕向ける代替法として
SET
max_seeks_for_key=
を利用する事ができます。詳しくは
項4.2.3. 「システム変数」
を参照してください。
value
データベースを明示的に指定する為に、デフォルト
データベース内で
tbl_name
、または
db_name
.tbl_name
としてテーブルを参照する事ができます。col_name
、tbl_name
.col_name
、または
db_name
.tbl_name
.col_name
としてカラムを参照する事ができます。参照が曖昧にならなければ、カラムの参照に
tbl_name
か
db_name
.tbl_name
プリフィックスを指定する必要はありません。さらに明確なカラム参照フォームを必要とする例に関しては、項8.2.1. 「識別子の修飾語」
を参照してください。
テーブル参照では
か
tbl_name
AS
alias_name
tbl_name alias_name
利用してエイリアスを指定する事ができます。
SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name; SELECT t1.name, t2.salary FROM employee t1, info t2 WHERE t1.name = t2.name;
アウトプットに選択されたカラムは、カラム名、カラム
エイリアス、またはカラム位置を利用して
ORDER BY
と GROUP BY
条項の中で参照する事ができます。カラム位置は整数で、1から始まります。
SELECT college, region, seed FROM tournament ORDER BY region, seed; SELECT college, region AS r, seed AS s FROM tournament ORDER BY r, s; SELECT college, region, seed FROM tournament ORDER BY 2, 3;
逆の順番にソートする為には、ソートに利用している
ORDER BY
条項の中で、カラム名に DESC
(降順)キーワードを追加してください。デフォルトは昇順です。これは
ASC
キ-ワードを利用して明示的に指定する事ができます。
カラム位置の利用は、構文が SQL スタンダードから削除された為に今後廃止される可能性があります。
もし GROUP BY
を利用すると、アウトプット行は GROUP
BY
に従って、まるで同じカラムに
ORDER BY
を持っていたかのようにソートされます。GROUP
BY
が生成するソートのオーバーヘッドを防ぐには、ORDER
BY NULL
を追加してください。
SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL;
MySQL
は、条項の中で名づけられたカラムの後ろに
ASC
と DESC
を指定する事もできるように、GROUP
BY
条項を拡張します。
SELECT a, COUNT(b) FROM test_table GROUP BY a DESC;
MySQL は、GROUP BY
条項内で言及されていないフィールドの選択を許可する為に、
GROUP BY
の利用を拡張します。もしクエリから期待通りの結果を得る事ができないのであれば、項11.11. 「GROUP BY
句との関数および修飾子の使用」
内の GROUP BY
の説明を読んでください。
GROUP BY
は WITH
ROLLUP
修飾因子を許容します。詳しくは
項11.11.2. 「GROUP BY
修飾子」
を参照してください。
HAVING
条項は、最後の方で項目がクライアントに送られる直前に、最適化無しで適応されます。(LIMIT
は HAVING
の後で適応されます。)
SQL スタンダードは HAVING
が
GROUP BY
条項の中、または総計関数の中で利用されるカラムだけを参照する事を要求します。しかし、MySQL
はこの動作に拡張子をサポートし、HAVING
が SELECT
リストの中のカラムと外部のサブクエリの中のカラムを参照する事を許容します。
もし HAVING
条項が曖昧なカラムを参照すると、警告が発生します。次のステートメントの中では、エイリアスとカラム名の両方として利用されている為
col2
は曖昧です。
SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
スタンダード SQL
の動作には優先権が与えられるので、もし
HAVING
カラム名が GROUP
BY
と、アウトプット カラム
リスト内のエイリアスカラムの両方で利用されると、優先権は
GROUP BY
カラム内のカラムに与えられます。
HAVING
は、WHERE
条項内になければいけない項目に対しては利用しないでください。例えば、次のような物を書かないでください。
SELECTcol_name
FROMtbl_name
HAVINGcol_name
> 0;
代わりにこのように書いてください。
SELECTcol_name
FROMtbl_name
WHEREcol_name
> 0;
HAVING
条項は WHERE
条項が参照できない総計関数を参照する事ができます。
SELECT user, MAX(salary) FROM users GROUP BY user HAVING MAX(salary) > 10;
(これは MySQL の古いバージョンでは機能しませんでした。)
MySQL
は複製カラム名を許容します。これは、同じ名前の
select_expr
が複数存在できるという事です。これはスタンダード
SQL の拡張子です。 MySQL はまた GROUP
BY
と HAVING
が
select_expr
値を参照する事を許容するので、この結果は曖昧になり得ます。
SELECT 12 AS a, a FROM t GROUP BY a;
このステートメントの中では、両方のカラムが
a
という名前を持ちます。グループ分けに正しいカラムを利用する事を保障する為に、各
select_expr
に異なる名前を利用してください。
MySQL は select_expr
値の中、そして FROM
条項内のテーブル
カラムの中を検索する事で ORDER
BY
条項内の無条件のカラムやエイリアス参照を解決します。GROUP
BY
か HAVING
条項に対しては、select_expr
値内を検索する前に FROM
条項を検索します。(GROUP BY
と
HAVING
に対しては、ORDER
BY
に対するのと同じルールを利用した MySQL 5.0
以前の動作とは異なります。)
LIMIT
条項は SELECT
ステートメントに返された行数を制限するのに利用する事ができます。LIMIT
は、負数以外の整数定数でなければいけない、1つか2つの数値引数を取ります。(準備されたステートメントを利用している時以外)
その2つの引数のうち、最初の物は返される最初の行のオフセットを指定し、2つめの物は返される行の最高数を指定します。冒頭の行のオフセットは0です。(1ではありません)
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
全ての行を一定のオフセットから結果セットの最後まで検索するには、2つめのパラメータに大きい数字を利用する事ができます。このステートメントは96番目の行から最後まで全ての行を検索します。
SELECT * FROM tbl LIMIT 95,18446744073709551615;
1つの引数で、その値は結果セットの最初から返される行数を指定します。
SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows
言い換えると、LIMIT
は
row_count
LIMIT 0,
と同等だという事になります。
row_count
用意されたステートメントには、プレースホルダを利用する事ができます。次のステートメントは
tbl
テーブルから行を1つ返します。
SET @a=1; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?'; EXECUTE STMT USING @a;
次のステートメントは tbl
テーブルから2行目から6行目を返します。
SET @skip=1; SET @numrows=5; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?'; EXECUTE STMT USING @skip, @numrows;
PostgreSQL との互換性に対しては、MySQL はまた
LIMIT
構文もサポートします。
row_count
OFFSET
offset
SELECT
の SELECT ... INTO
OUTFILE
'
型は選択された行をファイルに書き込みます。ファイルはサーバ
ソフト上に作成されるので、この構文を利用するには
file_name
'FILE
権限を持たなければいけません。
file_name
は、/etc/passwd
のようなファイルやデータベース
テーブルが、その他の物の間で破壊されるのを防ぐ既存ファイルにはなり得ません。MySQL
5.1.6
以降のバージョンでは、character_set_filesystem
システム変数は、ファイル名の解明をコントロールします。
SELECT ... INTO OUTFILE
ステートメントはそもそも、サーバ
マシン上のテキスト
ファイルにテーブルをすばやく捨てさせる事を意図しています。もしサーバ
ホストではなく、クライアント
ホスト上に結果ファイルを作成したければ、SELECT
... INTO OUTFILE
を利用する事はできません。その場合、クライアント
ホスト上にファイルを生成する為には、代わりに
mysql -e "SELECT ..." >
のようなコマンドを利用しなければいけません。
file_name
SELECT ... INTO OUTFILE
は LOAD
DATA INFILE
の補数です。ステートメントの
export_options
部分の構文は、LOAD DATA INFILE
ステートメントと共に利用される物と同じ
FIELDS
と LINES
条項で成り立っています。詳しくは
項12.2.5. 「LOAD DATA INFILE
構文」 を参照してください。
FIELDS ESCAPED BY
は、特別な文字をどのように書き込むのかをコントロールします。もし
FIELDS ESCAPED BY
文字が空でなければ、それはアウトプット上で次の文字に先行するプリフィックスとして利用されます。
FIELDS ESCAPED BY
文字
FIELDS [OPTIONALLY] ENCLOSED BY
文字
FIELDS TERMINATED BY
と
LINES TERMINATED BY
値の最初の文字
ASCII NUL
(ゼロの値のバイト;実際に拡張文字の後ろに書かれているのは、ゼロの値のバイトではなく、ASCII
‘0
’です。)
FIELDS TERMINATED BY
、ENCLOSED
BY
、ESCAPED BY
、または
LINES TERMINATED BY
文字は、ファイルを確実に読み返す事ができるように、拡張
されなければいけません。
ASCII NUL
は、ポケベルで見やすくする為に拡張されています。
結果のファイルは SQL 構文と一致する必要がないので、他の物は拡張される必要はありません。
もし FIELDS ESCAPED BY
文字が空なら、文字が拡張される事はなく、NULL
は \N
ではなく
NULL
としてアウトプットされます。特に、もしデータ中のにフィールド値が先ほどのリストの中の文字を含んでいる場合は、空の拡張文字を指定するのは良い考えではないかも知れません。
ここに、多くのプログラムで利用されるカンマで区切られた値(CSV)のフォーマットのファイルを生成する例があります。
SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM test_table;
もし INTO OUTFILE
の代わりに
INTO DUMPFILE
を利用すると、MySQL
は、カラムやラインのターミネーションや、拡張操作を行う事無く、ファイルの中に行を1つだけ書き込みます。
これは、もしファイルの中に
BLOB
値を格納したいのであれば有効です。
INTO
条項は、複数のユーザ定義変数のリストに名前をつける事ができます。選択された値は変数に割り当てられます。変数の数はカラム数と一致しなければいけません。
ストアド
ルーチンの中では、その変数はルーチン
パラメータかローカル変数になり得ます。詳しくは
項17.2.7.3. 「SELECT ... INTO
ステートメント」
を参照してください。
注意:INTO
OUTFILE
か INTO DUMPFILE
によって作成されたファイルは、サーバホスト上で全てのユーザによって書き込まれます。この理由は、MySQL
サーバは、それを起動させているアカウントの持ち主であるユーザ以外によって所有されているファイルを作成する事はできない
という事です。(これらの理由の為に、mysqld
を root
として起動する事は絶対にしてはいけません。)ですので、このファイルは内容を真似する事ができるように、誰でも修正ができる物である必要があります。
このセクションの最初の SELECT
構文の説明で、ステートメントの終わりの方の
INTO
条項が表されています。FROM
条項に先行して、INTO OUTFILE
か
INTO DUMPFILE
を直接利用する事も可能です。
PROCEDURE
条項は、結果セットの中にデータを処理しなければいけないプロシージャに名前をつけます。(例については、項25.4.1. 「Procedure Analyse」
をご覧ください。)
もしページか行ロックを利用するストレージ
エンジンと FOR UPDATE
を一緒に利用するなら、クエリに検査された行は現在のトランザクションが終わるまで書き込みロックされます。
LOCK IN SHARE MODE
を利用すると、他のトランザクションが検査された行を読む事は許容しますが、それらを更新や削除する事は許容しない共通ロックを設定します。詳しくは
項13.5.10.5. 「SELECT ... FOR UPDATE
と SELECT ... LOCK IN
SHARE MODE
ロック読み取り」
を参照してください。
SELECT
キーワードの後で、ステートメントの操作に影響を与える幾つかのオプションを利用する事ができます。
ALL
、DISTINCT
、そして
DISTINCTROW
オプションは、複製行が返されるべきかどうかを指定します。もしこれらのオプションが何も与えられなければ、デフォルトは
ALL
です。(全ての一致する行が返されます。)DISTINCT
と DISTINCTROW
は同義語で、結果セットから複製行を削除する指示を出します。
HIGH_PRIORITY
、STRAIGHT_JOIN
、そして
SQL_
で始まるオプションは、スタンダード SQL の
MySQL 拡張子です。
HIGH_PRIORITY
は
SELECT
に、テーブルを更新するステートメントよりも高い優先順位を与えます。これは、スピードがとても速く、一度に実行されなければいけないクエリに対してだけ利用して下さい。読み込みの為にテーブルがロックされている間に発行された
SELECT HIGH_PRIORITY
クエリは、テーブルがフリーになるのを待っている更新ステートメントがあったとしても実行します。
HIGH_PRIORITY
は、UNION
の一部である
SELECT
ステートメントと一緒には利用できません。
STRAIGHT_JOIN
は、オプチマイザが
FROM
条項内にリストされている順番でテーブルに結合するよう働きかけます。もし最適化ツールが、最適ではない順番でテーブルに接合した時、クエリのスピードを早くする為にこれを利用する事ができます。詳しくは
項6.2.1. 「EXPLAIN
を使用して、クエリを最適化する」
を参照してください。STRAIGHT_JOIN
はまた table_references
リストの中でも利用できます。詳しくは
項12.2.7.1. 「JOIN
構文」 を参照してください。
SQL_BIG_RESULT
は、オプチマイザに結果セットが行を多く持っている事を教える為に
GROUP BY
か DISTINCT
と共に利用する事ができます。この場合、MySQL
は必要であればディスク
ベースのテンポラリ
テーブルを直接利用し、GROUP BY
要素上のキーを持つテンポラリ
テーブルを利用してソートします。
SQL_BUFFER_RESULT
は結果がテンポラリ
テーブルの中に置かれるよう働きかけます。これは、MySQL
がテーブル
ロックを早く解除するのを助け、クライアントに結果セットを送るのに時間がかかる場合に補助します。
SQL_BIG_RESULT
は、オプチマイザに結果セットが小さい事を教える為に
GROUP BY
か DISTINCT
と共に利用する事ができます。この場合、MySQL
は結果テーブルを格納する為、ソート機能を利用する代わりに高速のテンポラリ
テーブルを利用します。通常これは必要ではないでしょう。
SQL_CALC_FOUND_ROWS
は全ての
LIMIT
条項を無視して、結果セットの中にいくつ行があるかを計算するよう
MySQL に指示します。 行数は SELECT
FOUND_ROWS()
を利用して検索する事ができます。詳しくは
項11.10.3. 「情報関数」
を参照してください。
2
or DEMAND
の
query_cache_type
値を利用している場合、SQL_CACHE
は、クエリ
キャッシュの中にクエリの結果を格納するよう
MySQL に指示します。
このオプションは、UNION
かサブクエリを利用するクエリに対して、クエリ中の全ての
SELECT
に影響を与えます。詳しくは
項4.13. 「MySQL クエリ キャッシュ」 を参照してください。
SQL_NO_CACHE
は MySQL
に対して、クエリ
キャッシュ内のクエリの結果を格納しないように指示します。詳しくは
項4.13. 「MySQL クエリ キャッシュ」
を参照してください。UNION
かサブクエリを利用するクエリに対して、このオプションはクエリ中の全ての
SELECT
に影響を与えます。