無料PHPプログラム

MySQL 5.1 リファレンスマニュアル :: 12 SQL ステートメント構文 :: 12.2 データ取り扱いステートメント :: 12.2.7 SELECT 構文
« 12.2.6 REPLACE 構文

12.2.7.1 JOIN 構文 »
Section Navigation      [Toggle]
  • 12.2 データ取り扱いステートメント
  • 12.2.1 DELETE 構文
  • 12.2.2 DO 構文
  • 12.2.3 HANDLER 構文
  • 12.2.4 INSERT 構文
  • 12.2.5 LOAD DATA INFILE 構文
  • 12.2.6 REPLACE 構文
  • 12.2.7 SELECT 構文
    • 12.2.7.1 JOIN 構文
    • 12.2.7.2 UNION 構文
  • 12.2.8 サブクエリ構文
  • 12.2.9 TRUNCATE 構文
  • 12.2.10 UPDATE 構文

12.2.7. SELECT 構文

[+/-]

12.2.7.1. JOIN 構文
12.2.7.2. UNION 構文
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, ...
    [FROM table_references
    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [HAVING where_condition]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ...]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [PROCEDURE procedure_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 table_references はどのテーブルから行の検索をするかを指示します。もし複数のテーブルに名前をつけると、それは結合を実行するという事になります。結合構文の情報に関しては、項12.2.7.1. 「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=value を利用する事ができます。詳しくは 項4.2.3. 「システム変数」 を参照してください。

  • データベースを明示的に指定する為に、デフォルト データベース内で 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 条項内になければいけない項目に対しては利用しないでください。例えば、次のような物を書かないでください。

    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 に異なる名前を利用してください。

  • 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 に影響を与えます。

Copyright c 1997, 2010, Oracle and/or its affiliates. All rights reserved. Legal Notices
Top / Previous / Next / Up / Table of Contents
© 2010, Oracle Corporation and/or its affiliates

無料CGI PHPスクリプト | 新着情報スクリプト | 営業日カレンダー | PHPマニュアル | MySQLマニュアル | PEARマニュアル

Copyright (c) 2010 jmcodex.com All rights reserved.