sql >> データベース >  >> RDS >> Mysql

MySQLサブクエリを操作する方法

    サブクエリ 別のSQLクエリ内にネストされたSQL(構造化クエリ言語)クエリです。サブクエリがネストされているコマンドは、親クエリと呼ばれます。サブクエリは、親クエリで使用されるデータを前処理するために使用されます。サブクエリはSELECTで適用できます 、INSERTUPDATE 、およびDELETE 操作。

    サブクエリが実行されると、サブクエリは親クエリの前に最初に処理されます。 MySQLアプリケーションを構築する場合、サブクエリを使用するといくつかの利点があります。

    • SQLステートメントを単純な論理ユニットに分割します。これにより、SQLステートメントの理解と保守が容易になります。つまり、サブクエリはクエリの複雑な部分を分離するのに役立ちます。
    • 複雑なUNIONを使用する必要がなくなります ステートメントとJOIN ステートメント。
    • 外部キーが実装されていないシナリオで参照の整合性を強制するために使用されます。
    • 開発者がビジネスロジックをMySQLクエリにコーディングするのに役立ちます。

    このガイドでは、次のことを学びます。

    • 相関サブクエリの使用方法
    • 比較演算子で相関サブクエリを使用する方法
    • サブクエリを派生テーブルとして使用する方法

    始める前に

    このガイドに従うには、次のものがあることを確認してください。

    1. まだ行っていない場合は、Linodeアカウントとコンピュートインスタンスを作成します。 Linode入門とコンピューティングインスタンスの作成ガイドをご覧ください。

    2. コンピューティングインスタンスのセットアップと保護ガイドに従って、システムを更新してください。また、タイムゾーンを設定し、ホスト名を構成し、制限付きユーザーアカウントを作成し、SSHアクセスを強化することもできます。

    3. LinodeにインストールされているMySQLサーバーソフトウェア(またはMariaDB)。いくつかのLinuxディストリビューションにMySQLをインストールする方法を説明するガイドが含まれているMySQLセクションを参照してください。

    データベースのセットアップ

    サブクエリがどのように機能するかを理解するには、最初にサンプルデータベースを作成します。このサンプルデータベースは、このガイドのさまざまなサンプルクエリを実行するために使用されます。

    1. SSH サーバーにアクセスし、rootとしてMySQLにログインします:

       mysql -u root -p
      

      プロンプトが表示されたら、MySQLサーバーのrootパスワードを入力し、 Enterを押します。 続ける。 MySQLサーバーのルートパスワードはLinodeのルートパスワードと同じではないことに注意してください。

      パスワードが受け入れられない場合は、sudoを使用して前のコマンドを実行する必要がある場合があります :

      sudo mysql -u root -p
      
    2. パスワードが受け入れられると、MySQLプロンプトが表示されます:

      
      mysql >
      

      MariaDBを使用している場合は、代わりに次のようなプロンプトが表示される場合があります。

      
      MariaDB [(none)]>
      
    3. test_dbという名前のサンプルデータベースを作成するには 、実行:

      CREATE DATABASE test_db;
      

      データベースが正常に作成されたことを確認する次の出力が表示されます。

      
      Query OK, 1 row affected (0.01 sec)
      
    4. test_dbに切り替えます データベース:

      USE test_db;
      

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

      
      Database changed
      
    5. test_dbを作成しました そしてそれを選択しました。次に、customersという名前のテーブルを作成します :

       CREATE TABLE customers
       (
       customer_id BIGINT PRIMARY KEY AUTO_INCREMENT,
       customer_name VARCHAR(50)
       ) ENGINE = InnoDB;
      

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

      
      Query OK, 0 rows affected (0.03 sec)
      
    6. customersにいくつかのレコードを追加します テーブル。以下のINSERTを実行します コマンドを1つずつ:

      INSERT INTO customers(customer_name) VALUES ('JOHN PAUL');
      INSERT INTO customers(customer_name) VALUES ('PETER DOE');
      INSERT INTO customers(customer_name) VALUES ('MARY DOE');
      INSERT INTO customers(customer_name) VALUES ('CHRISTINE JAMES');
      INSERT INTO customers(customer_name) VALUES ('MARK WELL');
      INSERT INTO customers(customer_name) VALUES ('FRANK BRIAN');
      

      この出力は、各レコードが挿入された後に表示されます:

      
      Query OK, 1 row affected (0.00 sec)
      ...
      
    7. 顧客の情報がデータベースに挿入されたことを確認します。このSELECTを実行します コマンド:

        SELECT *
        FROM
        customers;
      

      次の顧客リストが表示されます:

      
      +-------------+-----------------+
      | customer_id | customer_name   |
      +-------------+-----------------+
      |           1 | JOHN PAUL       |
      |           2 | PETER DOE       |
      |           3 | MARY DOE        |
      |           4 | CHRISTINE JAMES |
      |           5 | MARK WELL       |
      |           6 | FRANK BRIAN     |
      +-------------+-----------------+
      6 rows in set (0.00 sec)
      
    8. salesを作成します テーブル。このテーブルでは、列customer_idを使用しています customersを参照するには テーブル:

      CREATE TABLE sales
      (
      order_id BIGINT PRIMARY KEY AUTO_INCREMENT,
      customer_id BIGINT,
      sales_amount DECIMAL(17,2)
      ) ENGINE = InnoDB;
      

      この出力が表示されます:

      
      Query OK, 0 rows affected (0.03 sec)
      
    9. 次に、salesにデータを入力します いくつかのレコードを持つテーブル。以下のINSERTを実行します コマンドを1つずつ:

      INSERT INTO sales (customer_id, sales_amount) VALUES ('1','25.75');
      INSERT INTO sales (customer_id, sales_amount) VALUES ('2','85.25');
      INSERT INTO sales (customer_id, sales_amount) VALUES ('5','3.25');
      INSERT INTO sales (customer_id, sales_amount) VALUES ('4','200.75');
      INSERT INTO sales (customer_id, sales_amount) VALUES ('5','88.10');
      INSERT INTO sales (customer_id, sales_amount) VALUES ('1','100.00');
      INSERT INTO sales (customer_id, sales_amount) VALUES ('2','45.00');
      INSERT INTO sales (customer_id, sales_amount) VALUES ('4','15.80');
      

      この出力は、各レコードが挿入された後に表示されます:

      
      Query OK, 1 row affected (0.01 sec)
      ...
      
    10. salesのデータを確認します テーブル。このSELECTを実行します コマンド:

      SELECT * FROM sales;
      

      この販売データのリストが表示されます:

      
      +----------+-------------+--------------+
      | order_id | customer_id | sales_amount |
      +----------+-------------+--------------+
      |        1 |           1 |        25.75 |
      |        2 |           2 |        85.25 |
      |        3 |           5 |         3.25 |
      |        4 |           4 |       200.75 |
      |        5 |           5 |        88.10 |
      |        6 |           1 |       100.00 |
      |        7 |           2 |        45.00 |
      |        8 |           4 |        15.80 |
      +----------+-------------+--------------+
      8 rows in set (0.00 sec)
      

    データベースと関連テーブルを設定した後、MySQLでさまざまなサブクエリを実装できるようになりました。

    相関サブクエリの使用方法

    相関サブクエリは、親クエリの値を使用するネストされたクエリの一種です。これらの種類のクエリは、列を持つ親クエリを参照します。ネストされたクエリは、親クエリの行ごとに1回実行されます。

    以下の例は、すべての顧客を選択するクエリを示しています。クエリ内には、salesから各顧客の合計売上高を取得する相関サブクエリがあります。 テーブル。

    1. クエリ例を実行します:

      SELECT
      customer_id,
      customer_name,
      (SELECT SUM(sales_amount)
      FROM sales WHERE customer_id = customers.customer_id) as total_sales_amount
      FROM
      customers;
      

      この例では、サブクエリはSELECT SUM(sales_amount) FROM sales WHERE customer_id = customers.customer_idです。 、括弧内に表示されます。

      顧客の総売上高のリストが表示されます:

      
      +-------------+-----------------+--------------------+
      | customer_id | customer_name   | total_sales_amount |
      +-------------+-----------------+--------------------+
      |           1 | JOHN PAUL       |             125.75 |
      |           2 | PETER DOE       |             130.25 |
      |           3 | MARY DOE        |               NULL |
      |           4 | CHRISTINE JAMES |             216.55 |
      |           5 | MARK WELL       |              91.35 |
      |           6 | FRANK BRIAN     |               NULL |
      +-------------+-----------------+--------------------+
      6 rows in set (0.00 sec)
      

      相関サブクエリからの上記の出力は、顧客の注文の要約リストを提供することができます。 customer_idなので、注意してください ■3 および6 salesテーブルに関連するレコードがありません。それらのtotal_sales_amount NULLです 。

    2. このリストを表示するためのより洗練された方法は、0を返すことです。 NULLの代わりに 売上がゼロのお客様向け。これを行うには、サブクエリによって生成された出力をIFNULL(expression, 0)で囲みます。 声明。この更新されたコマンドを実行します:

       SELECT
       customer_id,
       customer_name,
       IFNULL((SELECT SUM(sales_amount)
       FROM sales WHERE customer_id = customers.customer_id), 0) as total_sales_amount
       FROM
       customers;
      

      次の出力が表示されます。 MySQLは、そうでなければNULLを返したはずのすべての行に対して0.00を返します。 値。

      
      +-------------+-----------------+--------------------+
      | customer_id | customer_name   | total_sales_amount |
      +-------------+-----------------+--------------------+
      |           1 | JOHN PAUL       |             125.75 |
      |           2 | PETER DOE       |             130.25 |
      |           3 | MARY DOE        |               0.00 |
      |           4 | CHRISTINE JAMES |             216.55 |
      |           5 | MARK WELL       |              91.35 |
      |           6 | FRANK BRIAN     |               0.00 |
      +-------------+-----------------+--------------------+
      6 rows in set (0.00 sec)
      

      このアプローチは、出力がレコードのそれ以上の計算に悪影響を与えないようにするのに役立ちます。

    比較演算子で相関サブクエリを使用する方法

    サブクエリは、ビジネスロジックをデータベースクエリレベルに移動するのに役立ちます。次のビジネスユースケースは、親クエリのWHERE句内に配置された相関サブクエリを特徴としています。

    • データベースに登録されている、売上が関連付けられていないすべての顧客のリストを取得したいシナリオを考えてみます。サブクエリは、MySQL比較演算子NOT INと一緒に使用できます。 これらの顧客を取得します:

        SELECT
        customer_id,
        customer_name
        FROM
        customers
        WHERE customer_id NOT IN (SELECT customer_id FROM sales);
      

      この例では、サブクエリはSELECT customer_id FROM salesです。 、括弧内に表示されます。上記のSQLコマンドは、salesテーブルにない2つの顧客のリストを出力します。

      
      +-------------+---------------+
      | customer_id | customer_name |
      +-------------+---------------+
      |           3 | MARY DOE      |
      |           6 | FRANK BRIAN   |
      +-------------+---------------+
      2 rows in set (0.00 sec)
      

      実稼働環境では、この種のレコードセットを使用して、より適切なビジネス上の意思決定を行うことができます。たとえば、PHPやPythonなどの別の言語を使用してスクリプトを作成し、これらの顧客にメールを送信して、注文に問題があるかどうかを問い合わせることができます。

    • もう1つのユースケースは、データのクリーンアップです。たとえば、サブクエリを使用して、注文したことのない顧客を削除できます。

        DELETE
        FROM
        customers
        WHERE customer_id NOT IN (SELECT customer_id FROM sales);
      

      上記のSQLコマンドは、2つの顧客を削除し、以下を出力します。

      
      Query OK, 2 rows affected (0.01 sec)
      

      コマンドを実行してすべての顧客を再度一覧表示すると、これらの顧客はテーブルに表示されなくなります。

        SELECT *
        FROM
        customers;
      

      以下の出力は、関連する注文のない顧客が削除されたことを確認します。

      
      +-------------+-----------------+
      | customer_id | customer_name   |
      +-------------+-----------------+
      |           1 | JOHN PAUL       |
      |           2 | PETER DOE       |
      |           4 | CHRISTINE JAMES |
      |           5 | MARK WELL       |
      +-------------+-----------------+
      4 rows in set (0.00 sec)
      

    サブクエリを派生テーブルとして使用する方法

    FROMでサブクエリが使用されている場合 親クエリの句。派生テーブルと呼ばれます。 。これらは、MySQL VIEWを必要とする複雑なクエリを実装する場合に非常に重要です。 、JOIN 、またはUNION 句。派生テーブルは、それを作成したクエリに存在し、データベースに永続的に保存されません。

    サブクエリを派生テーブルとして使用する場合、サブクエリはSQLステートメントのさまざまな部分を分離します。つまり、サブクエリは、親クエリのスコープ内で使用できるテーブルの簡略化された式を提供します。

    注 すべての派生テーブルはエイリアス化する必要があることを忘れないでください。

    以下のコマンドを実行して、order_summaryとしてエイリアスされる派生テーブルサブクエリを作成します :

    SELECT customer_id
    FROM
        (
        SELECT
        customer_id,
        count(order_id) as total_orders
        FROM sales
        group by customer_id
        ) as order_summary
    WHERE order_summary.total_orders > 1;
    

    このコマンドでは、サブクエリは括弧内に次のように表示されます。

    SELECT
    customer_id,
    count(order_id) as total_orders
    FROM sales
    group by customer_id
    

    上記のコマンドは、salesテーブルにクエリを実行して、複数の注文がある顧客を特定します。クエリを実行すると、次の出力が表示されます:

    
    +-------------+
    | customer_id |
    +-------------+
    |           1 |
    |           2 |
    |           5 |
    |           4 |
    +-------------+
    4 rows in set (0.00 sec)
    

    上記のリストは、4つのcustomer_idを示しています。 s複数の注文がある。ビジネスのユースケースの例として、次の購入で顧客にボーナスを与えるスクリプトでこのようなクエリを使用できます。

    詳細情報

    このトピックの詳細については、次のリソースを参照してください。これらは有用であることを期待して提供されていますが、外部でホストされている資料の正確性や適時性を保証することはできません。

    • MySQLサブクエリ

    1. CSVデータをPostgreSQLデータベース(リモートデータベース)に挿入する方法

    2. SQLiteでミリ秒を日付に変換する方法

    3. Oracleデータベースにファイルを挿入する方法は?

    4. Oracleで数字をローマ数字としてフォーマットする方法