SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr] ...
[into_option]
[FROM table_references
[PARTITION partition_list]]
[WHERE where_condition]
[GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
[HAVING where_condition]
[WINDOW window_name AS (window_spec)
[, window_name AS (window_spec)] ...]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[into_option]
[FOR {UPDATE | SHARE}
[OF tbl_name [, tbl_name] ...]
[NOWAIT | SKIP LOCKED]
| LOCK IN SHARE MODE]
[into_option]
into_option: {
INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name] ...
}
SELECT
は、1 つ以上のテーブルから選択された行を取得するために使用され、UNION
ステートメントとサブクエリーを含めることができます。 セクション13.2.10.3「UNION 句」およびセクション13.2.11「サブクエリー」を参照してください。 SELECT
ステートメントは、WITH
句で始まり、SELECT
内でアクセス可能な共通テーブル式を定義できます。 セクション13.2.15「WITH (共通テーブル式)」を参照してください。
SELECT
ステートメントのもっとも一般的に使用される句は次のとおりです。
各
select_expr
は、取得するカラムを示します。 少なくとも 1 つのselect_expr
が存在する必要があります。table_references
は、行を取得する 1 つまたは複数のテーブルを示します。 その構文については、セクション13.2.10.2「JOIN 句」で説明されています。SELECT
では、table_reference
のテーブル名の後にパーティションまたはサブパーティション (あるいはその両方) のリストを含むPARTITION
を使用した明示的なパーティション選択がサポートされています (セクション13.2.10.2「JOIN 句」 を参照)。 この場合、行はリストされているパーティションからのみ選択され、テーブルのほかのパーティションはすべて無視されます。 詳細および例については、セクション24.5「パーティション選択」を参照してください。-
WHERE
句 (指定されている場合) は、選択されるために行が満たす必要のある 1 つまたは複数の条件を示します。where_condition
は、選択される各行に対して true に評価される式です。WHERE
句がない場合、このステートメントはすべての行を選択します。WHERE
式では、集計 (グループ) 関数を除き、MySQL でサポートされている任意の関数および演算子を使用できます。 セクション9.5「式」および第12章「関数と演算子」を参照してください。
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
句は、構文の説明で示されている任意の位置に指定できますが、特定のステートメント内に指定できるのは一度のみで、複数の位置には指定できません。 INTO
の詳細は、セクション13.2.10.1「SELECT ... INTO ステートメント」を参照してください。
select_expr
項のリストは、どのカラムを取得するかを示す選択リストで構成されています。 これらの項はカラムや式を指定するか、または *
の短縮形を使用できます。
-
1 つの修飾されていない
*
のみから成る選択リストは、すべてのテーブルのすべてのカラムを選択するための短縮形として使用できます。SELECT * FROM t1 INNER JOIN t2 ...
-
は、指定されたテーブルのすべてのカラムを選択するための修飾された短縮形として使用できます。tbl_name
.*SELECT t1.*, t2.* FROM t1 INNER JOIN t2 ...
テーブルに非表示カラムがある場合、
*
および
には非表示カラムは含まれません。 非表示カラムを含めるには、明示的に参照する必要があります。tbl_name
.*-
修飾されていない
*
を選択リスト内のほかの項目とともに使用すると、解析エラーが生成される可能性があります。 この問題を回避するには、修飾された
参照を使用します。:tbl_name
.*SELECT AVG(score), t1.* FROM t1 ...
次のリストは、その他の SELECT
句に関する追加情報を示しています。
-
AS
を使用して、alias_name
select_expr
にエイリアスを指定できます。 エイリアスは式のカラム名として使用され、GROUP BY
、ORDER BY
、またはHAVING
句で使用できます。 例:SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;
select_expr
にエイリアスとして識別子を指定する場合、AS
キーワードはオプションです。 前の例は、次のように記述することもできました。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.3.4.4「カラムエイリアスに関する問題」を参照してください。 -
FROM
句は、行を取得する 1 つまたは複数のテーブルを示します。 複数のテーブルを指定すると、結合が実行されます。 結合構文については、セクション13.2.10.2「JOIN 句」を参照してください。 指定されたテーブルごとに、オプションでエイリアスを指定できます。table_references
tbl_name [[AS] alias] [index_hint]
インデックスヒントを使用すると、クエリー処理中にインデックスを選択する方法に関する情報がオプティマイザに提供されます。 これらのヒントを指定するための構文については、セクション8.9.4「インデックスヒント」を参照してください。
代わりの方法として
SET max_seeks_for_key=
を使用して、MySQL にテーブルスキャンの代わりにキースキャンを強制的に実行させることができます。 セクション5.1.8「サーバーシステム変数」を参照してください。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
プリフィクスを指定する必要はありません。 より明示的なカラム参照形式を必要とするあいまいさの例については、セクション9.2.2「識別子の修飾子」を参照してください。-
テーブル参照は、
またはtbl_name
ASalias_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
キーワードを使用して明示的に指定できます。ORDER BY
がカッコで囲まれたクエリー式内で発生し、外部クエリーにも適用される場合、結果は未定義であり、将来のバージョンの MySQL で変更される可能性があります。カラム位置の使用は、この構文が SQL 標準から削除されたため非推奨です。
-
MySQL 8.0.13 より前では、MySQL は
GROUP BY
カラムの明示的なASC
またはDESC
指定子を許可する非標準の構文拡張をサポートしていました。 MySQL 8.0.12 以降では、グループ化関数を使用したORDER BY
がサポートされているため、この拡張機能を使用する必要はなくなりました。 (Bug #86312、Bug #26073525) これは、GROUP BY
の使用時に次のように任意のカラムでソートできることも意味します:SELECT a, b, COUNT(c) AS t FROM test_table GROUP BY a,b ORDER BY a,t DESC;
MySQL 8.0.13 では、
GROUP BY
拡張機能はサポートされなくなりました:GROUP BY
カラムのASC
またはDESC
指定子は許可されていません。 ORDER BY
またはGROUP BY
を使用してSELECT
のカラムをソートする場合、max_sort_length
システム変数で指定された初期バイト数のみを使用して値がソートされます。MySQL では、
GROUP BY
の使用が、GROUP BY
句で指定されていないフィールドの選択を許可するように拡張されています。 クエリーから期待する結果が得られない場合は、セクション12.20「集計関数」にあるGROUP BY
の説明を参照してください。-
GROUP BY
では、WITH ROLLUP
修飾子が許可されます。 セクション12.20.2「GROUP BY 修飾子」を参照してください。以前は、
WITH ROLLUP
修飾子を持つクエリーでORDER BY
を使用することはできませんでした。 この制限は、MySQL 8.0.12 の時点でなくなりました。 セクション12.20.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
カラム内のカラムが優先されます。 -
WHERE
句に含めるべき項目にはHAVING
を使用しないでください。 たとえば、次のように記述しないでください。SELECT col_name FROM tbl_name HAVING col_name > 0;
代わりに、次のように記述してください。
SELECT col_name FROM tbl_name WHERE col_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
ごとに異なる名前を使用してください。 WINDOW
句が存在する場合は、ウィンドウ関数で参照できる名前付きウィンドウを定義します。 詳細は、セクション12.21.4「名前付きウィンドウ」を参照してください。MySQL は、
ORDER BY
句内の修飾されていないカラムまたはエイリアス参照を、まずselect_expr
値、次にFROM
句内のテーブルのカラム内を検索することによって解決します。GROUP BY
またはHAVING
句の場合は、select_expr
値内を検索する前にFROM
句を検索します。 (GROUP BY
とHAVING
について、これは、ORDER BY
) の場合と同じルールを使用していた MySQL 5.0 より前の動作とは異なります。-
LIMIT
句を使用すると、SELECT
ステートメントによって返される行数を制約できます。LIMIT
は 1 つまたは 2 つの数値引数を受け取ります。これは、どちらも負ではない整定数である必要があります。ただし、次の例外があります。準備済みステートメント内では、
?
プレースホルダマーカーを使用してLIMIT
パラメータを指定できます。ストアドプログラム内では、整数値のルーチンパラメータまたはローカル変数を使用して
LIMIT
パラメータを指定できます。
引数が 2 つの場合、最初の引数は返す先頭行のオフセットを指定し、2 番目の引数は返す行の最大数を指定します。 最初の行のオフセットは (1 ではなく) 0 です。
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
テーブルから行を戻します:SET @a=1; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?'; EXECUTE STMT USING @a;
次のステートメントは、
tbl
テーブルから秒から 6 行目を戻します:SET @skip=1; SET @numrows=5; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?'; EXECUTE STMT USING @skip, @numrows;
PostgreSQL との互換性のために、MySQL は
LIMIT
構文もサポートしています。row_count
OFFSEToffset
LIMIT
がカッコで囲まれたクエリー式内で発生し、外部クエリーにも適用される場合、結果は未定義であり、将来のバージョンの MySQL で変更される可能性があります。 SELECT
のSELECT ... INTO
形式を使用すると、クエリー結果をファイルに書き込んだり、変数に格納したりできます。 詳細は、セクション13.2.10.1「SELECT ... INTO ステートメント」を参照してください。-
FOR UPDATE
をページロックまたは行ロックを使用するストレージエンジンとともに使用する場合、クエリーによって検査される行は、現在のトランザクションが終了するまで書き込みロックされます。CREATE TABLE
などのステートメントでnew_table
SELECT ... FROMold_table
...SELECT
の一部としてFOR UPDATE
を使用することはできません。 (それを行おうとすると、このステートメントはエラー Can't update table 'old_table
' while 'new_table
' is being createdで拒否されます。)FOR SHARE
およびLOCK IN SHARE MODE
では、他のトランザクションが調査された行を読み取ることはできるが、更新または削除することはできない共有ロックが設定されます。FOR SHARE
とLOCK IN SHARE MODE
は同等です。 ただし、FOR UPDATE
と同様に、FOR SHARE
はNOWAIT
、SKIP LOCKED
およびOF
オプションをサポートしています。tbl_name
FOR SHARE
はLOCK IN SHARE MODE
の代替機能ですが、LOCK IN SHARE MODE
は下位互換性のために引き続き使用できます。NOWAIT
では、FOR UPDATE
またはFOR SHARE
クエリーがすぐに実行され、別のトランザクションによってロックが保持されているために行ロックを取得できない場合はエラーが返されます。SKIP LOCKED
では、別のトランザクションによってロックされている結果セットから行を除外して、FOR UPDATE
またはFOR SHARE
クエリーがただちに実行されます。NOWAIT
およびSKIP LOCKED
オプションは、ステートメントベースレプリケーションでは安全ではありません。注記ロックされた行をスキップするクエリーは、データの一貫性のないビューを返します。 したがって、
SKIP LOCKED
は一般的なトランザクション作業には適していません。 ただし、複数のセッションが同じキューに類似したテーブルにアクセスする場合、ロックの競合を回避するために使用できます。OF
は、tbl_name
FOR UPDATE
およびFOR SHARE
クエリーを名前付きテーブルに適用します。 例:SELECT * FROM t1, t2 FOR SHARE OF t1 FOR UPDATE OF t2;
OF
を省略すると、クエリーブロックによって参照されるすべてのテーブルがロックされます。 したがって、別のロック句と組み合せてtbl_name
OF
なしでロック句を使用すると、エラーが返されます。 複数のロック句で同じテーブルを指定すると、エラーが返されます。 エイリアスがtbl_name
SELECT
ステートメントでテーブル名として指定されている場合、ロック句ではエイリアスのみを使用できます。SELECT
ステートメントでエイリアスが明示的に指定されていない場合、ロック句では実際のテーブル名のみを指定できます。FOR UPDATE
およびFOR SHARE
の詳細は、セクション15.7.2.4「読取りのロック」 を参照してください。NOWAIT
およびSKIP LOCKED
オプションの詳細は、NOWAIT および SKIP LOCKED による読取り同時実行性のロック を参照してください。
SELECT
キーワードの後に、ステートメントの操作に影響を与える多数の修飾子を使用できます。 HIGH_PRIORITY
、STRAIGHT_JOIN
および SQL_
以降の修飾子は、標準 SQL に対する MySQL の拡張機能です。
-
ALL
修飾子およびDISTINCT
修飾子は、重複する行を戻すかどうかを指定します。ALL
(デフォルト) は、重複を含め、一致するすべての行を返すように指定します。DISTINCT
は、重複した行の結果セットからの削除を指定します。 両方の修飾子を指定するとエラーになります。DISTINCTROW
はDISTINCT
のシノニムです。MySQL 8.0.12 以降では、
WITH ROLLUP
も使用するクエリーでDISTINCT
を使用できます。 (Bug #87450、Bug #26640100) -
HIGH_PRIORITY
では、テーブルを更新するステートメントよりもSELECT
の優先度が高くなります。 これは、非常に高速であり、かつただちに実行する必要のあるクエリーにのみ使用するようにしてください。 テーブルが読み取りに対してロックされている間に発行されたSELECT HIGH_PRIORITY
クエリーは、そのテーブルが未使用になるのを待機している更新ステートメントが存在する場合でも実行されます。 これは、テーブルレベルロックのみを使用するストレージエンジン (MyISAM
、MEMORY
、およびMERGE
) にのみ影響を与えます。HIGH_PRIORITY
を、UNION
の一部であるSELECT
ステートメントで使用することはできません。 -
STRAIGHT_JOIN
では、オプティマイザによって、FROM
句にリストされている順序でテーブルが結合されます。 オプティマイザがテーブルを最適でない順序で結合する場合は、これを使用してクエリーを高速化できます。STRAIGHT_JOIN
はまた、table_references
リストでも使用できます。 セクション13.2.10.2「JOIN 句」を参照してください。STRAIGHT_JOIN
は、オプティマイザがconst
またはsystem
テーブルとして扱うテーブルには適用されません。 このようなテーブルは単一行を生成し、クエリー実行の最適化フェーズ中に読み取られます。また、そのカラムへの参照は、クエリー実行が続行される前に適切なカラム値で置き換えられます。 これらのテーブルは、EXPLAIN
によって表示されるクエリー計画の最初に表示されます。 「セクション8.8.1「EXPLAIN によるクエリーの最適化」」を参照してください。 この例外は、外部結合のNULL
で補完された側で使用されているconst
テーブルまたはsystem
テーブル (つまり、LEFT JOIN
の右側のテーブルまたはRIGHT JOIN
の左側のテーブル) には適用されない可能性があります。 -
SQL_BIG_RESULT
またはSQL_SMALL_RESULT
をGROUP BY
またはDISTINCT
とともに使用して、結果セットに多数の行があるか、それぞれ小さいことをオプティマイザに伝えることができます。SQL_BIG_RESULT
の場合、MySQL ではディスクベースの一時テーブルが直接使用され (作成されている場合)、GROUP BY
要素のキーを使用した一時テーブルよりソートが優先されます。SQL_SMALL_RESULT
の場合、MySQL では、ソートを使用するかわりにインメモリー一時テーブルを使用して結果テーブルを格納します。 これは、通常は必要ないはずです。 -
SQL_BUFFER_RESULT
では、結果が強制的に一時テーブルに格納されます。 これは、MySQL がテーブルロックを早期に解放する場合や、結果セットをクライアントに送信するのに長い時間がかかる場合に役立ちます。 この修飾子は、トップレベルのSELECT
ステートメントにのみ使用でき、サブクエリーやUNION
の後には使用できません。 -
SQL_CALC_FOUND_ROWS
は、LIMIT
句に関係なく、結果セットに存在する行数を計算するように MySQL に指示します。 そのあと、行数はSELECT FOUND_ROWS()
を使用して取得できます。 セクション12.16「情報関数」を参照してください。注記SQL_CALC_FOUND_ROWS
クエリー修飾子および付随するFOUND_ROWS()
関数は、MySQL 8.0.17 で非推奨になりました。これらは、MySQL の将来のバージョンで削除される予定です。 代替戦略の詳細は、FOUND_ROWS()
の説明を参照してください。 -
SQL_CACHE
およびSQL_NO_CACHE
修飾子は、MySQL 8.0 より前のクエリーキャッシュで使用されていました。 クエリーキャッシュは MySQL 8.0 で削除されました。SQL_CACHE
修飾子も削除されました。SQL_NO_CACHE
は非推奨であり、効果はありません。将来の MySQL リリースで削除される予定です。