はじめに
この実験(Lab)では、SQLite のサブクエリのテクニックを探求し、データの取得とフィルタリングの能力を高めます。WHERE
句内でサブクエリを使用する方法、SELECT
ステートメントに埋め込む方法、および相関サブクエリを構築する方法を学びます。
この実験(Lab)では、SQLite のサブクエリのテクニックを探求し、データの取得とフィルタリングの能力を高めます。WHERE
句内でサブクエリを使用する方法、SELECT
ステートメントに埋め込む方法、および相関サブクエリを構築する方法を学びます。
この最初のステップでは、departments
テーブルとemployees
テーブルの 2 つのテーブルを作成し、いくつかのサンプルデータを挿入します。これにより、次のステップでサブクエリを使用する練習に必要なデータが提供されます。
まず、LabEx VM でターミナルを開きます。デフォルトのパスは/home/labex/project
です。
開始するには、company.db
という名前の SQLite データベースに接続します。データベースが存在しない場合、SQLite が自動的に作成します。次のコマンドを実行します。
sqlite3 company.db
このコマンドは、SQLite コマンドラインツールを開き、company.db
データベースに接続します。sqlite>
プロンプトが表示されます。
次に、次の SQL コマンドを使用してdepartments
テーブルを作成します。
CREATE TABLE departments (
department_id INTEGER PRIMARY KEY,
department_name TEXT,
location TEXT
);
このコマンドは、departments
という名前のテーブルを、department_id
、department_name
、およびlocation
の 3 つのカラムで作成します。department_id
カラムは、このテーブルの主キー(primary key)です。
次に、いくつかのサンプルデータをdepartments
テーブルに挿入します。
INSERT INTO departments (department_name, location) VALUES
('Sales', 'New York'),
('Marketing', 'Los Angeles'),
('Engineering', 'San Francisco');
このコマンドは、departments
テーブルに 3 つの行を挿入し、3 つの異なる部署とその場所を表します。
次に、次の SQL コマンドを使用してemployees
テーブルを作成します。
CREATE TABLE employees (
employee_id INTEGER PRIMARY KEY,
employee_name TEXT,
department_id INTEGER,
FOREIGN KEY (department_id) REFERENCES departments(department_id)
);
このコマンドは、employees
という名前のテーブルを、employee_id
、employee_name
、およびdepartment_id
の 3 つのカラムで作成します。department_id
カラムは、departments
テーブルのdepartment_id
カラムを参照する外部キー(foreign key)です。
最後に、いくつかのサンプルデータをemployees
テーブルに挿入します。
INSERT INTO employees (employee_name, department_id) VALUES
('Alice', 1),
('Bob', 2),
('Charlie', 1),
('David', 3);
このコマンドは、employees
テーブルに 4 つの行を挿入し、4 つの異なる従業員とその部署 ID を表します。
このステップでは、WHERE
句でサブクエリを使用して、別のクエリの出力に基づいて結果をフィルタリングする方法を学びます。
サブクエリとは、別の SQL ステートメント内にネストされたSELECT
ステートメントのことです。この場合、サブクエリを使用してdepartments
テーブルからdepartment_id
の値を選択し、それらの値を使用してemployees
テーブルに対するクエリの結果をフィルタリングします。
'New York'に所在する部署で働くすべての従業員を見つけましょう。これを行うには、まず'New York'にある部署のdepartment_id
を見つけ、次にそのdepartment_id
を持つすべての従業員を見つける必要があります。
sqlite>
プロンプトで、次の SQL コマンドを入力します。
SELECT employee_name FROM employees WHERE department_id IN (SELECT department_id FROM departments WHERE location = 'New York');
このコマンドは、サブクエリによって返されるdepartment_id
の値のリストにdepartment_id
が含まれるemployees
テーブルからemployee_name
を選択します。サブクエリは、location
が'New York'であるdepartments
テーブルからdepartment_id
を選択します。
コマンドを実行すると、次の出力が表示されるはずです。
Alice
Charlie
この出力は、ニューヨークにある Sales 部門で働く従業員の名前を示しています。
このステップでは、SQL ステートメントのSELECT
句内にサブクエリを埋め込んで、関連するデータを取得する方法を学びます。
SELECT
句にサブクエリを埋め込むと、外側のクエリの各行に対して単一の値を取得できます。この値は、多くの場合、計算された値または別のテーブルからの関連する値です。
各従業員の名前と、その従業員の部署名を取得しましょう。sqlite>
プロンプトで、次の SQL コマンドを入力します。
SELECT employee_name, (SELECT department_name FROM departments WHERE department_id = employees.department_id) AS department_name FROM employees;
このコマンドは、employees
テーブルからemployee_name
を選択し、departments
テーブルからdepartment_name
を取得するサブクエリも含まれています。サブクエリは、employees
テーブルのdepartment_id
を使用して、正しい部署を照合します。サブクエリの結果は、department_name
としてエイリアス(alias)されます。
コマンドを実行すると、次の出力が表示されるはずです。
Alice|Sales
Bob|Marketing
Charlie|Sales
David|Engineering
この出力は、各従業員の名前と、対応する部署の名前を示しています。
このステップでは、相関サブクエリを構築する方法を学びます。相関サブクエリとは、外側のクエリのカラムを参照するサブクエリのことです。これは、サブクエリが外側のクエリの各行に対して一度実行されることを意味します。
一度実行され、その結果が外側のクエリで使用される単純なサブクエリとは異なり、相関サブクエリは、その値について外側のクエリに依存します。これらは、サブクエリ内の値を外側のクエリの現在の行の値と比較する必要がある場合に使用されます。
従業員の名前と同じ都市にある部署で働くすべての従業員を見つけましょう。これを機能させるために、まず従業員名を都市名に更新します。
UPDATE employees SET employee_name = 'New York' WHERE employee_name = 'Alice';
UPDATE employees SET employee_name = 'Los Angeles' WHERE employee_name = 'Bob';
UPDATE employees SET employee_name = 'New York' WHERE employee_name = 'Charlie';
UPDATE employees SET employee_name = 'San Francisco' WHERE employee_name = 'David';
これらのコマンドは、employees
テーブルのemployee_name
カラムを都市名に更新します。
次に、相関サブクエリを作成しましょう。
SELECT e.employee_name FROM employees e WHERE e.department_id IN (SELECT d.department_id FROM departments d WHERE d.location = e.employee_name);
このコマンドは、サブクエリによって返されるdepartment_id
の値のリストにdepartment_id
が含まれるemployees
テーブル(エイリアス(alias)e
)からemployee_name
を選択します。サブクエリは、departments
テーブル(エイリアス(alias)d
)から、location
が外側のクエリのemployee_name
と一致するdepartment_id
を選択します。
コマンドを実行すると、次の出力が表示されるはずです。
New York
Los Angeles
San Francisco
この出力は、同じ都市にある部署で働く従業員(現在は都市名)の名前を示しています。
このステップでは、サブクエリの効率を評価し、最適化のためにJOIN
操作を使用した代替アプローチを検討する方法を学びます。
サブクエリは強力ですが、特に大規模なデータセットでは、パフォーマンスのボトルネックにつながる場合があります。多くの場合、JOIN
操作を使用してサブクエリを書き換えることができ、その方が効率的な場合があります。
前のステップの相関サブクエリをJOIN
を使用して書き換えてみましょう。
SELECT e.employee_name FROM employees e JOIN departments d ON e.department_id = d.department_id WHERE d.location = e.employee_name;
このコマンドは、employees
テーブル(エイリアス(alias)e
)からemployee_name
を選択し、department_id
カラムでdepartments
テーブル(エイリアス(alias)d
)と結合(JOIN)します。次に、WHERE
句は、departments
テーブルのlocation
がemployees
テーブルのemployee_name
と一致する行のみを含めるように結果をフィルタリングします。
結果を確認するには、コマンドを実行します。前のステップと同じ出力が表示されるはずです。
New York
Los Angeles
San Francisco
効率を評価するには、通常、変更の前後にEXPLAIN QUERY PLAN
を使用します。ただし、LabEx 環境の制限により、EXPLAIN QUERY PLAN
コマンドを完全に実証することはできません。重要な点は、JOIN
操作は、特に大規模なデータセットの場合、相関サブクエリよりも効率的なことが多いということです。
最後に、sqlite3
シェルを終了します。
.exit
これにより、bash プロンプトに戻ります。
この実験(Lab)では、SQLite サブクエリを使用して、データの取得およびフィルタリング機能を強化する方法を学びました。WHERE
句内でサブクエリを使用し、SELECT
ステートメントに埋め込み、相関サブクエリを構築する練習をしました。また、効率を向上させるために、JOIN
操作を使用してサブクエリを書き換える方法も学びました。これらのテクニックは、SQLite でデータを操作するための強力なツールを提供します。