SQLite サブクエリ

サブクエリは、内部クエリまたはネストされたクエリとも呼ばれ、SQLite クエリの WHERE 句にクエリ文を埋め込むことを指します。

ある SELECT 文のクエリ結果は、別の文の入力値として使用できます。

サブクエリは SELECT、INSERT、UPDATE、DELETE 文と一緒に使用でき、=、<、>、>=、<=、IN、BETWEEN などの演算子と組み合わせて使用できます。

以下は、サブクエリが従わなければならないいくつかのルールです:

  • サブクエリは括弧で囲む必要があります。

  • サブクエリは SELECT 句内に1つの列しか持てません。ただし、メインクエリに複数の列があり、サブクエリで選択された列と比較する場合は除きます。

  • ORDER BY はサブクエリ内では使用できませんが、メインクエリでは ORDER BY を使用できます。サブクエリ内では GROUP BY を使用でき、その機能は ORDER BY と同じです。

  • サブクエリが複数行を返す場合、IN 演算子などの複数値演算子とのみ使用できます。

  • BETWEEN 演算子はサブクエリと一緒には使用できません。ただし、BETWEEN はサブクエリ内では使用できます。

SELECT 文でのサブクエリの使用

サブクエリは通常、SELECT 文と一緒に使用されます。基本構文は次のとおりです:

SELECT column_name [, column_name ]
FROM   table1 [, table2 ]
WHERE  column_name OPERATOR
      (SELECT column_name [, column_name ]
      FROM table1 [, table2 ]
      [WHERE])

例

COMPANY テーブルに次のレコードがあると仮定します:

ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
1           Paul        32          California  20000.0
2           Allen       25          Texas       15000.0
3           Teddy       23          Norway      20000.0
4           Mark        25          Rich-Mond   65000.0
5           David       27          Texas       85000.0
6           Kim         22          South-Hall  45000.0
7           James       24          Houston     10000.0

それでは、SELECT 文でのサブクエリの使用を確認してみましょう:

sqlite> SELECT * 
     FROM COMPANY 
     WHERE ID IN (SELECT ID 
                  FROM COMPANY 
                  WHERE SALARY > 45000) ;

これにより、次の結果が生成されます:

ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
4           Mark        25          Rich-Mond   65000.0
5           David       27          Texas       85000.0

INSERT 文でのサブクエリの使用

サブクエリは INSERT 文と一緒に使用することもできます。INSERT 文はサブクエリが返すデータを使用して、別のテーブルに挿入します。サブクエリで選択されたデータは、任意の文字、日付、または数値関数で変更できます。

基本構文は次のとおりです:

INSERT INTO table_name [ (column1 [, column2 ]) ]
           SELECT [ *|column1 [, column2 ]
           FROM table1 [, table2 ]
           [ WHERE VALUE OPERATOR ]

例

COMPANY_BKP の構造が COMPANY テーブルと類似しており、同じ CREATE TABLE を使用して作成できると仮定します。ただし、テーブル名は COMPANY_BKP に変更されます。次に、COMPANY テーブル全体を COMPANY_BKP にコピーします。構文は次のとおりです:

sqlite> INSERT INTO COMPANY_BKP
     SELECT * FROM COMPANY 
     WHERE ID IN (SELECT ID 
                  FROM COMPANY) ;

UPDATE 文でのサブクエリの使用

サブクエリは UPDATE 文と組み合わせて使用できます。UPDATE 文でサブクエリを使用すると、テーブル内の1つまたは複数の列が更新されます。

基本構文は次のとおりです:

UPDATE table
SET column_name = new_value
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

例

COMPANY テーブルのバックアップである COMPANY_BKP テーブルがあると仮定します。

次の例では、COMPANY テーブル内の AGE が27以上のすべての顧客の SALARY を元の0.50倍に更新します:

sqlite> UPDATE COMPANY
     SET SALARY = SALARY * 0.50
     WHERE AGE IN (SELECT AGE FROM COMPANY_BKP
                   WHERE AGE >= 27 );

これにより2行が影響を受け、最終的な COMPANY テーブルのレコードは次のようになります:

ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
1           Paul        32          California  10000.0
2           Allen       25          Texas       15000.0
3           Teddy       23          Norway      20000.0
4           Mark        25          Rich-Mond   65000.0
5           David       27          Texas       42500.0
6           Kim         22          South-Hall  45000.0
7           James       24          Houston     10000.0

DELETE 文でのサブクエリの使用

サブクエリは、前述の他の文と同様に、DELETE 文と組み合わせて使用できます。

基本構文は次のとおりです:

DELETE FROM TABLE_NAME
[ WHERE OPERATOR [ VALUE ]
   (SELECT COLUMN_NAME
   FROM TABLE_NAME)
   [ WHERE) ]

例

COMPANY テーブルのバックアップである COMPANY_BKP テーブルがあると仮定します。

次の例では、COMPANY テーブル内の AGE が27以上のすべての顧客レコードを削除します:

sqlite> DELETE FROM COMPANY
     WHERE AGE IN (SELECT AGE FROM COMPANY_BKP
                   WHERE AGE > 27 );

これにより2行が影響を受け、最終的な COMPANY テーブルのレコードは次のようになります:

ID          NAME        AGE         ADDRESS     SALARY
----------  ----------  ----------  ----------  ----------
2           Allen       25          Texas       15000.0
3           Teddy       23          Norway      20000.0
4           Mark        25          Rich-Mond   65000.0
5           David       27          Texas       42500.0
6           Kim         22          South-Hall  45000.0
7           James       24          Houston     10000.0
その他の拡張