SQL SELECTステートメントは、 1 つ以上のテーブルから行の結果セットを返します。[ 1 ] [ 2 ]
SELECT文は、1つ以上のデータベーステーブルまたはデータベースビューから0行以上の行を取得します。ほとんどのアプリケーションでは、SELECT最も一般的に使用されるデータ操作言語(DML)コマンドです。SQLは宣言型プログラミング言語であるため、SELECTクエリは結果セットを指定しますが、計算方法は指定しません。データベースはクエリを「クエリプラン」に変換します。このクエリプランは、実行、データベースのバージョン、およびデータベースソフトウェアによって異なる場合があります。この機能は、適用可能な制約内でクエリに最適な実行プランを見つける役割を担うため、 「クエリオプティマイザ」と呼ばれます。
SELECT文には多くのオプション句があります。
SELECTlist は、クエリによって返される列または SQL 式のリストです。これは、関係代数における射影演算にほぼ相当します。ASオプションで、リスト内の各列または式にエイリアスを指定できますSELECT。これは関係代数における名前変更操作です。FROMデータを取得するテーブルを指定します。[ a ]WHERE取得する行を指定します。これは、関係代数における選択演算にほぼ相当します。GROUP BY共通のプロパティを持つ行をグループ化することで、各グループに集計関数を適用できるようにする。HAVINGGROUP BY句で定義されたグループの中から選択します。ORDER BY返される行の順序を指定します。SELECTSQL で最も一般的な操作は「クエリ」と呼ばれます。SELECTは 1 つ以上のテーブルまたは式からデータを取得します。標準SELECTステートメントはデータベースに永続的な影響を与えません。 の非標準実装の中には、一部のデータベースで提供されている構文SELECTのように、永続的な影響を与えるものもありますSELECT INTO。[ 3 ]
クエリを使用すると、ユーザーは必要なデータを記述でき、データベース管理システム(DBMS)は、その結果を生成するために必要な計画、最適化、および物理的な操作を、DBMSが選択した方法で実行します。
クエリには、最終結果に含める列のリストが含まれ、通常はSELECTキーワードの直後に続きます。アスタリスク(" *")を使用すると、クエリがすべてのクエリ対象テーブルのすべての列を返すように指定できます。SELECTは、SQLで最も複雑なステートメントであり、オプションのキーワードと句には以下が含まれます。
FROM句は、データを取得するテーブルを指定します。このFROM句にはJOIN、テーブル結合のルールを指定するためのオプションの副句を含めることができます。WHERE句には比較述語が含まれており、クエリによって返される行を制限します。このWHERE句は、比較述語が真と評価されないすべての行を結果セットから除外します。GROUP BY句は、共通の値を持つ行をより小さな行のセットに投影します。GROUP BYは、SQL 集計関数と組み合わせて使用したり、結果セットから重複行を削除したりするためによく使用されます。 このWHERE句は、 句の前に適用されますGROUP BY。HAVING句には、句の結果として得られる行をフィルタリングするために使用される述語が含まれていますGROUP BY。この述語は句の結果に対して作用するためGROUP BY、集計関数を句の述語内で使用できますHAVING。ORDER BY句は、結果データをソートするために使用する列と、ソート方向(昇順または降順)を指定します。このORDER BY句がない場合、SQLクエリによって返される行の順序は未定義です。DISTINCTは重複データを削除します。[ 5 ]次のSELECTクエリ例は、高価な書籍のリストを返します。このクエリは、Bookテーブルから、価格列の値が 100.00 より大きいすべての行を取得します。結果は、タイトルの昇順でソートされます。選択リストのアスタリスク (*) は、Bookテーブルのすべての列を結果セットに含める必要があることを示しています。
SELECT * FROM Book WHERE price > 100.00 ORDER BY title ;以下の例は、複数のテーブルに対するクエリ、グループ化、および集計を行い、書籍のリストと各書籍に関連付けられた著者の数を返す方法を示しています。
SELECT Book.title AS Title , count ( * ) AS Authors FROM Book JOIN Book_author ON Book.isbn = Book_author.isbn GROUP BY Book.title ;出力例は以下のようになるでしょう。
タイトル 著者 ---------------------- ------- SQLの例とガイド4 SQLの楽しさ 1 SQL入門2 SQLの落とし穴 1
isbn が2 つのテーブルに共通する唯一の列名であり、 titleという名前の列はBookテーブルにのみ存在するという前提条件の下では、上記のクエリを次の形式で書き直すことができます。
SELECT title , count ( * ) AS Authors FROM Book NATURAL JOIN Book_author GROUP BY title ;しかし、多くのベンダーはこのアプローチをサポートしていないか、自然結合を効果的に機能させるために特定の列命名規則を要求します。
SQLには、格納された値に対して値を計算するための演算子と関数が含まれています。SQLでは、次の例のように、 SELECTリストで式を使用してデータを投影できます。この例では、価格が100.00を超える書籍のリストが返され、さらに価格の6%で計算された売上税額を含むsales_tax列が追加されます。
SELECT isbn , title , price , price * 0 . 06 AS sales_tax FROM Book WHERE price > 100 . 00 ORDER BY title ;クエリはネストできるため、あるクエリの結果を関係演算子または集計関数を介して別のクエリで使用できます。ネストされたクエリはサブクエリとも呼ばれます。結合やその他のテーブル操作は、多くの場合(実装によって異なりますが)、計算効率に優れた(つまり高速な)代替手段を提供しますが、サブクエリを使用すると、実行時に階層構造が導入され、これが有用または必要となる場合があります。次の例では、集計関数はAVG入力としてサブクエリの結果を受け取ります。
SELECT isbn , title , price FROM Book WHERE price < ( SELECT AVG ( price ) FROM Book ) ORDER BY title ;サブクエリは外部クエリの値を使用できます。この場合、相関サブクエリと呼ばれます。
1999年以降、SQL標準ではWITH句、つまり共通テーブル式(CTE)と呼ばれる名前付きサブクエリが使用可能になりました(IBM DB2バージョン2の実装に基づいて命名および設計されています。Oracleではこれをサブクエリファクタリングと呼んでいます)。CTEは自身を参照することで再帰的にも使用できます。このメカニズムにより、ツリーやグラフの走査(リレーションとして表現した場合)、そしてより一般的には不動点計算が可能になります。
派生テーブルとは、FROM句内のサブクエリのことです。つまり、派生テーブルは、選択または結合の対象となるサブクエリです。派生テーブル機能を使用すると、サブクエリをテーブルとして参照できます。派生テーブルは、インラインビューまたはFROMリスト内の選択とも呼ばれます。
次の例では、SQL文は元のBooksテーブルと派生テーブル「Sales」の結合を含んでいます。この派生テーブルは、ISBNを使用してBooksテーブルと結合することで、関連する書籍の販売情報を取得します。その結果、派生テーブルは、追加の列(販売されたアイテム数と書籍を販売した会社)を含む結果セットを提供します。
SELECT b.isbn , b.title , b.price , sales.items_sold , sales.company_nm FROM Book b JOIN ( SELECT SUM ( Items_Sold ) Items_Sold , Company_Nm , ISBN FROM Book_Sales GROUP BY Company_Nm , ISBN ) sales ON sales.isbn = b.isbnテーブルTが与えられた場合、クエリを 実行すると、テーブルのすべての行のすべての要素が表示されます。SELECT*FROMT
同じテーブルに対してクエリを実行すると、テーブルのすべての行の列C1の要素が表示されます。これは関係代数における射影に似ていますが、一般的には結果に重複する行が含まれる可能性があります。これはデータベース用語では垂直パーティションとも呼ばれ、クエリの出力を特定のフィールドまたは列のみに制限します。SELECTC1FROMT
同じテーブルに対してこのクエリを実行すると、列C1の値が「1」であるすべての行のすべての要素が表示されます。関係代数で言えば、 WHERE句によって選択が実行されます。これは水平パーティションとも呼ばれ、指定された条件に基づいてクエリの出力行を制限します。SELECT*FROMTWHEREC1=1
テーブルが複数ある場合、結果セットは行のすべての組み合わせになります。つまり、2つのテーブルがT1とT2の場合、 T1のすべての行とT2のすべての行のすべての組み合わせが結果になります。たとえば、T1に3行、T2に5行ある場合、15行の結果になります。SELECT*FROMT1,T2
標準規格ではないものの、ほとんどのDBMSでは、1行の仮想テーブルを使用しているかのように見せかけることで、テーブルを指定せずにSELECT句を使用できます。これは主に、テーブルを必要としない計算を実行する際に使用されます。
SELECT句では、プロパティ(列)のリストを名前で指定するか、ワイルドカード文字(「*」)を使用して「すべてのプロパティ」を指定します。
返される行数の上限を指定すると便利な場合が多い。これはテストに使用したり、クエリが予想よりも多くの情報を返す場合に過剰なリソース消費を防ぐために役立つ。この方法はベンダーによって異なることが多い。
ISO SQL:2003では、結果セットは以下のように制限される可能性があります。
ISO SQL:2008ではこのFETCH FIRST条項が導入されました。
PostgreSQL v.9 のドキュメントによると、SQL ウィンドウ関数は集計関数と同様の方法で、「現在の行と何らかの形で関連する一連のテーブル行に対して計算を実行する」ものです。[ 6 ] この名前は信号処理のウィンドウ関数を連想させます。ウィンドウ関数の呼び出しには必ずOVER句が含まれます。
ROW_NUMBER() OVER返された行に対して単純な表を作成する場合に使用できます。たとえば、10行以下を返す場合などです。
SELECT * FROM ( SELECT ROW_NUMBER () OVER ( ORDER BY sort_key ASC ) AS row_number , columns FROM tablename ) AS foo WHERE row_number <= 10ROW_NUMBERは非決定論的になる可能性があります。sort_keyが一意でない場合、クエリを実行するたびに、sort_keyが同じ行に異なる行番号が割り当てられる可能性があります。sort_keyが一意の場合、各行には常に一意の行番号が割り当てられます。
ウィンドウRANK() OVER関数はROW_NUMBERのように動作しますが、同順位の場合、 n行より多いまたは少ない行を返すことがあります。たとえば、最年少の上位10人を返す場合などです。
SELECT * FROM ( SELECT RANK () OVER ( ORDER BY age ASC ) AS ranking , person_id , person_name , age FROM person ) AS foo WHERE ranking <= 10上記のコードは10行以上を返す可能性があります。例えば、同い年の人が2人いる場合、11行を返す可能性があります。
ISO SQL:2008以降、句を使用して次の例のように結果の制限を指定できますFETCH FIRST。
SELECT * FROM T FETCH FIRST 10 ROWS ONLYこの条項は現在、CA DATACOM/DB 11、IBM DB2、SAP SQL Anywhere、PostgreSQL、EffiProz、H2、HSQLDBバージョン2.0、Oracle 12c、およびMimer SQLでサポートされています。
Microsoft SQL Server 2008 以降ではがサポートされていますFETCH FIRSTが、これはORDER BY句の一部とみなされます。ORDER BY、OFFSET、FETCH FIRST句はすべてこの用途に必要です。
SELECT * FROM T ORDER BY acolumn DESC OFFSET 0 ROWS FETCH FIRST 10 ROWS ONLY一部のDBMSは、SQL標準構文に加えて、またはそれに代わる非標準構文を提供しています。以下に、さまざまなDBMSにおける単純な制限クエリのバリエーションを示します。
行ページネーション[ 8 ]は、データベース内のクエリの全データの一部のみを制限して表示するために使用される手法です。数百または数千の行を同時に表示する代わりに、サーバーには1ページ(たとえば10行のみの限られた行のセット)のみが要求され、ユーザーは次のページ、さらに次のページを要求してナビゲートを開始します。これは、クライアントとサーバー間に専用の接続がないWebシステムで特に役立ちます。クライアントはサーバーのすべての行を読み込んで表示するのを待つ必要がないためです。
{rows}= ページ内の行数{page_number}= 現在のページ番号{begin_base_0}= ページの開始行番号 - 1 = (ページ番号 - 1) * 行数{begin_base_0 + 1}。{begin_base_0 + rows}{ table }から{ unique_key }で並べ替えて*を選択します。{begin_base_0 + rows}){begin_base_0 + rows}が、読み込んだ行の行番号が次の値より大きい場合にのみ表示に送信します。{begin_base_0}{rows}次の行から始まる行のみを選択して表示します( {begin_base_0 + 1}){rows}フィルターを使用して行のみ を選択します。{rows}最初のページ:データベースの種類に応じて、最初の行のみを選択します。{rows}次のページ:データベースの種類に応じて、 が(現在のページの最後の行のの値){unique_key}より大きい最初の行のみを選択します。{last_val}{unique_key}{rows}行のみを選択し、結果を正しい順序に並べ替えます。{unique_key}{first_val}{unique_key}一部のデータベースは、階層型データのための特殊な構文を提供しています。
SQL:2003におけるウィンドウ関数とは、結果セットのパーティションに適用される集計関数のことです。
例えば、
都市ごとの人口の合計現在の行と同じ都市値を持つすべての行の人口の合計を計算します。
パーティションは、集計値を変更するOVER句を使用して指定します。構文:
< OVER_CLAUSE > :: = OVER ( [ PARTITION BY < expr > , ... ] [ ORDER BY <式> ] ) OVER句を使用すると、結果セットを分割して順序付けできます。順序付けは、row_numberなどの順序関連関数で使用されます。
ANSI SQL に従って SELECT ステートメントを処理すると次のようになります。[ 9 ]
SELECT g . * FROM users u INNER JOIN groups g ON g.Userid = u.Userid WHERE u.LastName = ' Smith ' AND u.FirstName = ' John 'SELECT u . * FROM users u LEFT JOIN groups g ON g . Userid = u . Userid WHERE u . LastName = 'Smith' AND u . FirstName = 'John'SELECT g.GroupName , COUNT ( g . * ) AS NumberOfMembers FROM users u INNER JOIN groups g ON g.Userid = u.Userid GROUP BY GroupNameSELECT g.GroupName , COUNT ( g . * ) AS NumberOfMembers FROM users u INNER JOIN groups g ON g.Userid = u.Userid GROUP BY GroupName HAVING COUNT ( g . * ) > 5リレーショナルデータベースやSQLエンジンのベンダーによるウィンドウ関数機能の実装は大きく異なります。ほとんどのデータベースは、少なくとも何らかのウィンドウ関数をサポートしています。しかし、詳しく見てみると、ほとんどのベンダーは標準のサブセットしか実装していないことがわかります。強力なRANGE句を例にとってみましょう。この機能を完全に実装しているのは、Oracle、DB2、Spark/Hive、Google BigQueryだけです。最近では、ベンダーは配列集計関数など、標準に新しい拡張機能を追加しました。これらは、分散リレーショナルデータベース(MPP)よりもデータの共局在性の保証が弱い分散ファイルシステム(Hadoop、Spark、Google BigQuery)に対してSQLを実行する場合に特に役立ちます。分散ファイルシステムに対してクエリを実行するSQLエンジンは、データをすべてのノードに均等に分散するのではなく、データをネストすることでデータの共局在性保証を実現し、ネットワーク全体で大量のシャッフルを伴う可能性のある高コストな結合を回避できます。ウィンドウ関数で使用できるユーザー定義の集計関数も、非常に強力な機能です。
全てを結合したデータに基づいてデータを生成する方法
select 1 a , 1 b union all select 1 , 2 union all select 1 , 3 union all select 2 , 1 union all select 5 , 1SQL Server 2008 は、 SQL:1999標準で規定されている「行コンストラクター」機能をサポートしています。
select * from ( values ( 1 , 1 ), ( 1 , 2 ), ( 1 , 3 ), ( 2 , 1 ), ( 5 , 1 )) as x ( a , b )引数はDISTINCTと同一ですが、ANSI規格ではありません。
[...]キーワードDISTINCT[...]は結果セットから重複を削除します。