開発者ドキュメント

PostgreSQLのクエリの概要

序章

データベースは、多くのWebサイトやアプリケーションの重要なコンポーネントであり、インターネットを介してデータを保存および交換する方法の中核を成しています。 データベース管理の最も重要な側面の1つは、アドホックベースであろうと、アプリケーションにコード化されたプロセスの一部であろうと、データベースからデータを取得する方法です。 データベースから情報を取得する方法はいくつかありますが、最も一般的に使用される方法の1つは、コマンドラインからクエリを送信することによって実行されます。

リレーショナルデータベース管理システムでは、queryはテーブルからデータを取得するために使用される任意のコマンドです。 構造化照会言語(SQL)では、ほとんどの場合、照会はSELECTステートメントを使用して行われます。

このガイドでは、SQLクエリの基本的な構文と、より一般的に使用される関数と演算子のいくつかについて説明します。 また、PostgreSQLデータベースのサンプルデータを使用してSQLクエリを作成する練習も行います。

PostgreSQL は、しばしば「Postgres」と短縮され、オブジェクト指向アプローチを備えたリレーショナルデータベース管理システムです。つまり、情報をPostgreSQLスキーマのオブジェクトまたはクラスとして表すことができます。 PostgreSQLは標準SQLと緊密に連携していますが、他のリレーショナルデータベースシステムにはない機能もいくつか含まれています。

前提条件

一般に、このガイドに示されているコマンドと概念は、SQLデータベースソフトウェアを実行しているLinuxベースのオペレーティングシステムで使用できます。 ただし、PostgreSQLを実行しているUbuntu18.04サーバーを念頭に置いて特別に作成されています。 これを設定するには、次のものが必要です。

この設定が整ったら、チュートリアルを開始できます。

サンプルデータベースの作成

SQLでクエリを作成する前に、まずデータベースといくつかのテーブルを作成し、次にこれらのテーブルにサンプルデータを入力します。 これにより、後でクエリを作成し始めるときに、実践的な経験を積むことができます。

このガイド全体で使用するサンプルデータベースについて、次のシナリオを想像してください。

あなたとあなたの友人の何人かは皆、お互いにあなたの誕生日を祝います。 毎回、グループのメンバーは地元のボウリング場に向かい、フレンドリーなトーナメントに参加します。その後、全員があなたの場所に向かい、誕生日の人の好きな食事を準備します。

この伝統がしばらく続いているので、あなたはこれらのトーナメントからの記録を追跡し始めることに決めました。 また、夕食の計画を簡単にするために、友達の誕生日とお気に入りのメインディッシュ、サイドディッシュ、デザートの記録を作成することにしました。 この情報を物理的な元帳に保持するのではなく、PostgreSQLデータベースに記録してデータベーススキルを行使することにします。

まず、postgresスーパーユーザーとしてPostgreSQLプロンプトを開きます。

  1. sudo -u postgres psql

注: Ubuntu 18.04 へのPostgreSQLのインストールに関する前提条件のチュートリアルのすべての手順を実行した場合は、PostgreSQLインストールの新しい役割を構成している可能性があります。 この場合、sammyを自分のユーザー名に置き換えて、次のコマンドを使用してPostgresプロンプトに接続できます。

  1. sudo -u sammy psql

次に、以下を実行してデータベースを作成します。

  1. CREATE DATABASE birthdays;

次に、次のように入力してこのデータベースを選択します。

  1. \c birthdays

次に、このデータベース内に2つのテーブルを作成します。 最初のテーブルを使用して、ボウリング場での友達の記録を追跡します。 次のコマンドは、tourneysというテーブルを作成し、各友達のname、勝ったトーナメントの数(wins)、すべての列を示します。時間bestスコア、および彼らが着用するボウリングシューズのサイズ(size):

  1. CREATE TABLE tourneys (
  2. name varchar(30),
  3. wins real,
  4. best real,
  5. size real
  6. );

CREATE TABLEコマンドを実行して列見出しを入力すると、次の出力が表示されます。

Output
CREATE TABLE

tourneysテーブルにいくつかのサンプルデータを入力します。

  1. INSERT INTO tourneys (name, wins, best, size)
  2. VALUES ('Dolly', '7', '245', '8.5'),
  3. ('Etta', '4', '283', '9'),
  4. ('Irma', '9', '266', '7'),
  5. ('Barbara', '2', '197', '7.5'),
  6. ('Gladys', '13', '273', '8');

次の出力が表示されます。

Output
INSERT 0 5

これに続いて、同じデータベース内に別のテーブルを作成します。このテーブルを使用して、友達のお気に入りの誕生日の食事に関する情報を保存します。 次のコマンドは、dinnersという名前のテーブルを作成します。このテーブルには、各友達のnamebirthdate、お気に入りのentree、好みのside皿、そして彼らのお気に入りのdessert

  1. CREATE TABLE dinners (
  2. name varchar(30),
  3. birthdate date,
  4. entree varchar(30),
  5. side varchar(30),
  6. dessert varchar(30)
  7. );

同様に、このテーブルについては、テーブルが作成されたことを確認するフィードバックを受け取ります。

Output
CREATE TABLE

このテーブルにもいくつかのサンプルデータを入力します。

  1. INSERT INTO dinners (name, birthdate, entree, side, dessert)
  2. VALUES ('Dolly', '1946-01-19', 'steak', 'salad', 'cake'),
  3. ('Etta', '1938-01-25', 'chicken', 'fries', 'ice cream'),
  4. ('Irma', '1941-02-18', 'tofu', 'fries', 'cake'),
  5. ('Barbara', '1948-12-25', 'tofu', 'salad', 'ice cream'),
  6. ('Gladys', '1944-05-28', 'steak', 'fries', 'ice cream');
Output
INSERT 0 5

そのコマンドが正常に完了すると、データベースのセットアップは完了です。 次に、SELECTクエリの基本的なコマンド構造について説明します。

SELECTステートメントを理解する

はじめに述べたように、SQLクエリはほとんどの場合SELECTステートメントで始まります。 SELECTはクエリで使用され、テーブルのどの列を結果セットに返すかを指定します。 クエリには、ほとんどの場合FROMも含まれます。これは、ステートメントがクエリを実行するテーブルを指定するために使用されます。

通常、SQLクエリは次の構文に従います。

  1. SELECT column_to_select FROM table_to_select WHERE certain_conditions_apply;

例として、次のステートメントは、dinnersテーブルからname列全体を返します。

  1. SELECT name FROM dinners;
Output
name --------- Dolly Etta Irma Barbara Gladys (5 rows)

次のように、名前をコンマで区切ることにより、同じテーブルから複数の列を選択できます。

  1. SELECT name, birthdate FROM dinners;
Output
name | birthdate ---------+------------ Dolly | 1946-01-19 Etta | 1938-01-25 Irma | 1941-02-18 Barbara | 1948-12-25 Gladys | 1944-05-28 (5 rows)

特定の列または列のセットに名前を付ける代わりに、SELECT演算子の後にアスタリスク(*)を付けることができます。これは、テーブル内のすべての列を表すプレースホルダーとして機能します。 次のコマンドは、tourneysテーブルからすべての列を返します。

  1. SELECT * FROM tourneys;
Output
name | wins | best | size ---------+------+------+------ Dolly | 7 | 245 | 8.5 Etta | 4 | 283 | 9 Irma | 9 | 266 | 7 Barbara | 2 | 197 | 7.5 Gladys | 13 | 273 | 8 (5 rows)

WHEREは、指定された条件を満たすレコードをフィルタリングするクエリで使用され、その条件を満たす行は結果から削除されます。 WHERE句は通常、次の構文に従います。

  1. . . . WHERE column_name comparison_operator value

WHERE句の比較演算子は、指定された列を値と比較する方法を定義します。 一般的なSQL比較演算子は次のとおりです。

オペレーター それが何をするか
= 平等のテスト
!= 不平等のテスト
< 未満のテスト
> より大きいテスト
<= 以下または等しいかどうかをテストします
>= 以上または等しいかどうかをテストします
BETWEEN 値が指定された範囲内にあるかどうかをテストします
IN 行の値が指定された値のセットに含まれているかどうかをテストします
EXISTS 指定された条件で行が存在するかどうかをテストします
LIKE 値が指定された文字列と一致するかどうかをテストします
IS NULL NULL値のテスト
IS NOT NULL NULL以外のすべての値をテストします

たとえば、Irmaの靴のサイズを検索する場合は、次のクエリを使用できます。

  1. SELECT size FROM tourneys WHERE name = 'Irma';
Output
size ------ 7 (1 row)

SQLではワイルドカード文字を使用できます。これらはWHERE句で使用する場合に特に便利です。 パーセント記号(%)は0個以上の不明な文字を表し、アンダースコア(_)は単一の不明な文字を表します。 これらは、テーブル内の特定のエントリを検索しようとしているが、そのエントリが正確に何であるかがわからない場合に役立ちます。 説明のために、数人の友人のお気に入りのメインディッシュを忘れたが、この特定のメインディッシュは「t」で始まると確信しているとしましょう。 次のクエリを実行すると、その名前を見つけることができます。

  1. SELECT entree FROM dinners WHERE entree LIKE 't%';
Output
entree ------- tofu tofu (2 rows)

上記の出力に基づいて、忘れたメインディッシュはtofuであることがわかります。

比較的長い名前や読みにくい名前の列またはテーブルがあるデータベースを使用している場合があります。 このような場合、ASキーワードを使用してエイリアスを作成することにより、これらの名前を読みやすくすることができます。 ASで作成されたエイリアスは一時的なものであり、作成されたクエリの期間中のみ存在します。

  1. SELECT name AS n, birthdate AS b, dessert AS d FROM dinners;
Output
n | b | d ---------+------------+----------- Dolly | 1946-01-19 | cake Etta | 1938-01-25 | ice cream Irma | 1941-02-18 | cake Barbara | 1948-12-25 | ice cream Gladys | 1944-05-28 | ice cream (5 rows)

ここでは、name列をnとして、birthdate列をbとして、dessert列を次のように表示するようにSQLに指示しました。 d

これまでに行った例には、SQLクエリでより頻繁に使用されるキーワードと句が含まれています。 これらは基本的なクエリには役立ちますが、計算を実行したり、スカラー値(複数の異なる値のセットではなく単一の値)を導出しようとしている場合は役に立ちません。あなたのデータ。 ここで、集計関数が機能します。

集計関数

多くの場合、データを操作するとき、必ずしもデータ自体を見たいとは限りません。 むしろ、データに関する情報が必要です。 SQL構文には、SELECTクエリを発行するだけで、データの計算を解釈または実行できるようにする多数の関数が含まれています。 これらは集約関数として知られています。

COUNT関数は、特定の基準に一致する行数をカウントして返します。 たとえば、誕生日のメインディッシュに豆腐を好む友達の数を知りたい場合は、次のクエリを発行できます。

  1. SELECT COUNT(entree) FROM dinners WHERE entree = 'tofu';
Output
count ------- 2 (1 row)

AVG関数は、列の平均(平均)値を返します。 サンプルテーブルを使用すると、次のクエリで友達の平均最高スコアを見つけることができます。

  1. SELECT AVG(best) FROM tourneys;
Output
avg ------- 252.8 (1 row)

SUMは、特定の列の合計を見つけるために使用されます。 たとえば、あなたとあなたの友人が何年にもわたってボウリングしたゲームの数を確認したい場合は、次のクエリを実行できます。

  1. SELECT SUM(wins) FROM tourneys;
Output
sum ----- 35 (1 row)

AVGおよびSUM関数は、数値データで使用した場合にのみ正しく機能することに注意してください。 数値以外のデータでそれらを使用しようとすると、使用しているRDBMSに応じて、エラーまたは0のみが発生します。

  1. SELECT SUM(entree) FROM dinners;
Output
ERROR: function sum(character varying) does not exist LINE 1: select sum(entree) from dinners; ^ HINT: No function matches the given name and argument types. You might need to add explicit type casts.

MINは、指定された列内の最小値を見つけるために使用されます。 このクエリを使用して、これまでの全体的なボウリングの最悪の記録を確認できます(勝利数の観点から)。

  1. SELECT MIN(wins) FROM tourneys;
Output
min ----- 2 (1 row)

同様に、MAXは、特定の列で最大の数値を見つけるために使用されます。 次のクエリは、全体として最高のボウリング記録を示しています。

  1. SELECT MAX(wins) FROM tourneys;
Output
max ----- 13 (1 row)

SUMおよびAVGとは異なり、MINおよびMAX関数は、数値データ型とアルファベットデータ型の両方に使用できます。 文字列値を含む列で実行すると、MIN関数は最初の値をアルファベット順に表示します。

  1. SELECT MIN(name) FROM dinners;
Output
min --------- Barbara (1 row)

同様に、文字列値を含む列で実行すると、MAX関数は最後の値をアルファベット順に表示します。

  1. SELECT MAX(name) FROM dinners;
Output
max ------ Irma (1 row)

集計関数には、このセクションで説明した以外にも多くの用途があります。 これらは、GROUP BY句と一緒に使用すると特に便利です。この句については、結果セットの並べ替え方法に影響を与える他のいくつかのクエリ句とともに次のセクションで説明します。

クエリ出力の操作

FROMおよびWHERE句に加えて、SELECTクエリの結果を操作するために使用される他のいくつかの句があります。 このセクションでは、より一般的に使用されるいくつかのクエリ句の例を説明し、提供します。

FROMWHEREを除いて、最も頻繁に使用されるクエリ句の1つは、GROUP BY句です。 これは通常、ある列で集計関数を実行しているときに使用されますが、別の列の値の一致に関連しています。

たとえば、作成した3つのメインディッシュのそれぞれを好む友人の数を知りたいとします。 この情報は、次のクエリで見つけることができます。

  1. SELECT COUNT(name), entree FROM dinners GROUP BY entree;
Output
count | entree -------+--------- 1 | chicken 2 | steak 2 | tofu (3 rows)

ORDER BY句は、クエリ結果を並べ替えるために使用されます。 デフォルトでは、数値は昇順で並べ替えられ、テキスト値はアルファベット順に並べ替えられます。 説明のために、次のクエリはname列とbirthdate列を一覧表示しますが、結果を誕生日で並べ替えます。

  1. SELECT name, birthdate FROM dinners ORDER BY birthdate;
Output
name | birthdate ---------+------------ Etta | 1938-01-25 Irma | 1941-02-18 Gladys | 1944-05-28 Dolly | 1946-01-19 Barbara | 1948-12-25 (5 rows)

ORDER BYのデフォルトの動作は、結果セットを昇順でソートすることであることに注意してください。 これを逆にして結果セットを降順でソートするには、DESCでクエリを閉じます。

  1. SELECT name, birthdate FROM dinners ORDER BY birthdate DESC;
Output
name | birthdate ---------+------------ Barbara | 1948-12-25 Dolly | 1946-01-19 Gladys | 1944-05-28 Irma | 1941-02-18 Etta | 1938-01-25 (5 rows)

前述のように、WHERE句は、特定の条件に基づいて結果をフィルタリングするために使用されます。 ただし、集計関数でWHERE句を使用すると、エラーが返されます。これは、少なくとも3人の友達のお気に入りの側を見つけるための次の試みの場合と同様です。

  1. SELECT COUNT(name), side FROM dinners WHERE COUNT(name) >= 3;
Output
ERROR: aggregate functions are not allowed in WHERE LINE 1: SELECT COUNT(name), side FROM dinners WHERE COUNT(name) >= 3...

HAVING句がSQLに追加され、WHERE句と同様の機能を提供すると同時に、集計関数とも互換性があります。 WHEREは個々のレコードに適用され、HAVINGはグループレコードに適用されるという点で、これら2つの句の違いを考えると役立ちます。 このため、HAVING句を発行するときは常に、GROUP BY句も存在する必要があります。

次の例は、少なくとも3人の友人のお気に入りのおかずを見つけるための別の試みですが、これはエラーなしで結果を返します。

  1. SELECT COUNT(name), side FROM dinners GROUP BY side HAVING COUNT(name) >= 3;
Output
count | side -------+------- 3 | fries (1 row)

集計関数は、特定のテーブルの特定の列の結果を要約するのに役立ちます。 ただし、複数のテーブルの内容をクエリする必要がある場合が多くあります。 次のセクションでは、これを行うためのいくつかの方法について説明します。

複数のテーブルのクエリ

多くの場合、データベースには複数のテーブルが含まれ、それぞれが異なるデータセットを保持しています。 SQLは、複数のテーブルに対して単一のクエリを実行するためのいくつかの異なる方法を提供します。

JOIN句を使用して、クエリ結果の2つ以上のテーブルの行を組み合わせることができます。 これは、テーブル間の関連する列を見つけることによってこれを行い、出力で結果を適切にソートします。

SELECTステートメントは、通常、次の構文に従います。

  1. SELECT table1.column1, table2.column2
  2. FROM table1
  3. JOIN table2 ON table1.related_column=table2.related_column;

JOIN句は複数のテーブルの内容を比較するため、前の例では、列の名前の前にテーブルの名前とピリオドを付けて、各列を選択するテーブルを指定していることに注意してください。 前のセクションで行ったように、単一のテーブルから選択する場合は必要ありませんが、どのクエリに対してもこのように列を選択するテーブルを指定できます。 サンプルデータを使用して例を見ていきましょう。

友達の一人一人に誕生日プレゼントとしてボウリングシューズを買いたいと想像してみてください。 友達の生年月日と靴のサイズに関する情報は別々のテーブルに保持されているため、両方のテーブルを別々にクエリして、それぞれの結果を比較できます。 ただし、JOIN句を使用すると、1回のクエリで必要なすべての情報を見つけることができます。

  1. SELECT tourneys.name, tourneys.size, dinners.birthdate
  2. FROM tourneys
  3. JOIN dinners ON tourneys.name=dinners.name;
Output
name | size | birthdate ---------+------+------------ Dolly | 8.5 | 1946-01-19 Etta | 9 | 1938-01-25 Irma | 7 | 1941-02-18 Barbara | 7.5 | 1948-12-25 Gladys | 8 | 1944-05-28 (5 rows)

この例で使用されているJOIN句は、他の引数なしで、 inner JOIN句です。 これは、両方のテーブルで値が一致するすべてのレコードを選択して結果セットに出力し、一致しないレコードは除外されることを意味します。 このアイデアを説明するために、他のテーブルに対応するエントリがない新しい行を各テーブルに追加しましょう。

  1. INSERT INTO tourneys (name, wins, best, size)
  2. VALUES ('Bettye', '0', '193', '9');
  1. INSERT INTO dinners (name, birthdate, entree, side, dessert)
  2. VALUES ('Lesley', '1946-05-02', 'steak', 'salad', 'ice cream');

次に、前のSELECTステートメントをJOIN句を使用して再実行します。

  1. SELECT tourneys.name, tourneys.size, dinners.birthdate
  2. FROM tourneys
  3. JOIN dinners ON tourneys.name=dinners.name;
Output
name | size | birthdate ---------+------+------------ Dolly | 8.5 | 1946-01-19 Etta | 9 | 1938-01-25 Irma | 7 | 1941-02-18 Barbara | 7.5 | 1948-12-25 Gladys | 8 | 1944-05-28 (5 rows)

tourneysテーブルにはLesleyのエントリがなく、dinnersテーブルにはBettyeのエントリがないため、これらのレコードはこの出力に含まれていないことに注意してください。

ただし、 external JOIN句を使用して、テーブルの1つからすべてのレコードを返すことは可能です。 外側のJOIN句は、LEFT JOINRIGHT JOIN、またはFULL JOINのいずれかとして記述されます。

LEFT JOIN句は、「左側」のテーブルからすべてのレコードを返し、右側のテーブルから一致するレコードのみを返します。 外部結合のコンテキストでは、左側のテーブルはFROM句によって参照されるテーブルであり、右側のテーブルはJOINステートメントの後に参照される他のテーブルです。

前のクエリを再度実行しますが、今回はLEFT JOIN句を使用します。

  1. SELECT tourneys.name, tourneys.size, dinners.birthdate
  2. FROM tourneys
  3. LEFT JOIN dinners ON tourneys.name=dinners.name;

このコマンドは、右側のテーブルに対応するレコードがない場合でも、左側のテーブル(この場合はtourneys)からすべてのレコードを返します。 右側のテーブルに一致するレコードがない場合は常に、RDBMSに応じて、空白の値またはNULLとして返されます。

Output
name | size | birthdate ---------+------+------------ Dolly | 8.5 | 1946-01-19 Etta | 9 | 1938-01-25 Irma | 7 | 1941-02-18 Barbara | 7.5 | 1948-12-25 Gladys | 8 | 1944-05-28 Bettye | 9 | (6 rows)

ここで、今度はRIGHT JOIN句を使用して、クエリを再度実行します。

  1. SELECT tourneys.name, tourneys.size, dinners.birthdate
  2. FROM tourneys
  3. RIGHT JOIN dinners ON tourneys.name=dinners.name;

これにより、右側のテーブル(dinners)からすべてのレコードが返されます。 レスリーの生年月日は右側のテーブルに記録されていますが、左側のテーブルには対応する行がないため、name列とsize列はその行に空白の値として返されます。

Output
name | size | birthdate ---------+------+------------ Dolly | 8.5 | 1946-01-19 Etta | 9 | 1938-01-25 Irma | 7 | 1941-02-18 Barbara | 7.5 | 1948-12-25 Gladys | 8 | 1944-05-28 | | 1946-05-02 (6 rows)

句のOUTERの部分が暗示されていますが、左結合と右結合はLEFT OUTER JOINまたはRIGHT OUTER JOINと記述できることに注意してください。 同様に、INNER JOINを指定すると、JOINを書き込んだ場合と同じ結果が得られます。

FULL JOINと呼ばれる4番目の結合句があり、PostgreSQLを含む一部のRDBMSディストリビューションで使用できます。 FULL JOINは、null値を含む、各テーブルのすべてのレコードを返します。

  1. SELECT tourneys.name, tourneys.size, dinners.birthdate
  2. FROM tourneys
  3. FULL JOIN dinners ON tourneys.name=dinners.name;
Output
name | size | birthdate ---------+------+------------ Dolly | 8.5 | 1946-01-19 Etta | 9 | 1938-01-25 Irma | 7 | 1941-02-18 Barbara | 7.5 | 1948-12-25 Gladys | 8 | 1944-05-28 Bettye | 9 | | | 1946-05-02 (7 rows)

注:この記事の執筆時点では、FULL JOIN句はMySQLまたはMariaDBのいずれでもサポートされていません。

FULL JOINを使用して複数のテーブルのすべてのレコードをクエリする代わりに、UNION句を使用できます。

UNION演算子は、JOIN句とは少し異なる動作をします。単一のSELECTステートメントを使用して複数のテーブルからの結果を一意の列として出力する代わりにUNIONは2つのSELECTステートメントの結果を1つの列にまとめます。

説明のために、次のクエリを実行します。

  1. SELECT name FROM tourneys UNION SELECT name FROM dinners;

このクエリは、重複するエントリを削除します。これは、UNION演算子のデフォルトの動作です。

Output
name --------- Irma Etta Bettye Gladys Barbara Lesley Dolly (7 rows)

すべてのエントリ(重複を含む)を返すには、UNION ALL演算子を使用します。

  1. SELECT name FROM tourneys UNION ALL SELECT name FROM dinners;
Output
name --------- Dolly Etta Irma Barbara Gladys Bettye Dolly Etta Irma Barbara Gladys Lesley (12 rows)

結果テーブルの列の名前と数は、最初のSELECTステートメントによって照会された列の名前と数を反映しています。 UNIONを使用して複数のテーブルから複数の列をクエリする場合、各SELECTステートメントは同じ数の列をクエリする必要があり、それぞれの列は同様のデータ型である必要があり、それぞれの列は類似している必要があります。 SELECTステートメントは同じ順序である必要があります。 次の例は、異なる数の列をクエリする2つのSELECTステートメントでUNION句を使用するとどうなるかを示しています。

  1. SELECT name FROM dinners UNION SELECT name, wins FROM tourneys;
Output
ERROR: each UNION query must have the same number of columns LINE 1: SELECT name FROM dinners UNION SELECT name, wins FROM tourne...

複数のテーブルをクエリする別の方法は、サブクエリを使用することです。 サブクエリ(内部またはネストされたクエリとも呼ばれます)は、別のクエリに囲まれたクエリです。 これらは、クエリの結果を別の集計関数の結果に対してフィルタリングしようとしている場合に役立ちます。

このアイデアを説明するために、バーバラよりも多くの試合に勝った友達を知りたいとします。 バーバラが勝った試合の数をクエリしてから別のクエリを実行して、それより多くのゲームに勝った人を確認するのではなく、1つのクエリで両方を計算できます。

  1. SELECT name, wins FROM tourneys
  2. WHERE wins > (
  3. SELECT wins FROM tourneys WHERE name = 'Barbara'
  4. );
Output
name | wins --------+------ Dolly | 7 Etta | 4 Irma | 9 Gladys | 13 (4 rows)

このステートメントのサブクエリは1回だけ実行されました。 name列のBarbaraと同じ行のwins列から値を見つけるだけでよく、サブクエリと外部クエリによって返されるデータは独立しています。お互いに。 ただし、目的のデータを返すために、外部クエリが最初にテーブル内のすべての行を読み取り、それらの値をサブクエリによって返されたデータと比較する必要がある場合があります。 この場合、サブクエリは相関サブクエリと呼ばれます。

次のステートメントは、相関サブクエリの例です。 このクエリは、同じ靴のサイズの友達の平均よりも多くのゲームに勝った友達を見つけようとします。

  1. SELECT name, size FROM tourneys AS t
  2. WHERE wins > (
  3. SELECT AVG(wins) FROM tourneys WHERE size = t.size
  4. );

クエリを完了するには、最初に外部クエリからname列とsize列を収集する必要があります。 次に、その結果セットの各行を内部クエリの結果と比較します。これにより、同じ靴のサイズを持つ個人の平均勝利数が決定されます。 同じ靴のサイズの友達が2人しかいないため、結果セットには1つの行しかありません。

Output
name | size ------+------ Etta | 9 (1 row)

前述のように、サブクエリを使用して、複数のテーブルからの結果をクエリできます。 最後の例でこれを説明するために、グループの史上最高のボウラーのためにサプライズディナーを投げたいとしましょう。 次のクエリを使用して、ボウリングの記録が最も優れている友達を見つけて、お気に入りの食事を返すことができます。

  1. SELECT name, entree, side, dessert
  2. FROM dinners
  3. WHERE name = (SELECT name FROM tourneys
  4. WHERE wins = (SELECT MAX(wins) FROM tourneys));
Output
name | entree | side | dessert --------+--------+-------+----------- Gladys | steak | fries | ice cream (1 row)

このステートメントにはサブクエリが含まれているだけでなく、そのサブクエリ内にサブクエリも含まれていることに注意してください。

結論

クエリの発行は、データベース管理の領域で最も一般的に実行されるタスクの1つです。 phpMyAdminpgAdminなど、クエリを実行して結果を視覚化できるデータベース管理ツールがいくつかありますが、コマンドからSELECTステートメントを発行します。 lineは今でも広く実践されているワークフローであり、より優れた制御を提供することもできます。

SQLを初めて使用する場合は、 SQLチートシートを参照として使用し、公式のPostgreSQLドキュメントを確認することをお勧めします。 さらに、SQLおよびリレーショナルデータベースについて詳しく知りたい場合は、次のチュートリアルが役立つ場合があります。

モバイルバージョンを終了