このページは機械翻訳したものです。
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_nameselect_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_referencestbl_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_nameASalias_nametbl_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_countLIMIT 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_countOFFSEToffsetLIMITがカッコで囲まれたクエリー式内で発生し、外部クエリーにも適用される場合、結果は未定義であり、将来のバージョンの MySQL で変更される可能性があります。 SELECTのSELECT ... INTO形式を使用すると、クエリー結果をファイルに書き込んだり、変数に格納したりできます。 詳細は、セクション13.2.10.1「SELECT ... INTO ステートメント」を参照してください。-
FOR UPDATEをページロックまたは行ロックを使用するストレージエンジンとともに使用する場合、クエリーによって検査される行は、現在のトランザクションが終了するまで書き込みロックされます。CREATE TABLEなどのステートメントでnew_tableSELECT ... 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_nameFOR 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_nameFOR UPDATEおよびFOR SHAREクエリーを名前付きテーブルに適用します。 例:SELECT * FROM t1, t2 FOR SHARE OF t1 FOR UPDATE OF t2;OFを省略すると、クエリーブロックによって参照されるすべてのテーブルがロックされます。 したがって、別のロック句と組み合せてtbl_nameOFなしでロック句を使用すると、エラーが返されます。 複数のロック句で同じテーブルを指定すると、エラーが返されます。 エイリアスがtbl_nameSELECTステートメントでテーブル名として指定されている場合、ロック句ではエイリアスのみを使用できます。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 リリースで削除される予定です。