SQL GROUPING SETS

概要: このチュートリアルでは、SQL GROUPING SETS 演算子を使用して複数のグルーピングセットを生成する方法を学習します。

サンプルテーブルの設定

GROUPING SETS の機能を説明するために、inventory という名前の新しいテーブルを設定しましょう。

まず、inventory という名前の新しいテーブルを作成します。

CREATE TABLE inventory (
    warehouse VARCHAR(255),
    product VARCHAR(255) NOT NULL,
    model VARCHAR(50) NOT NULL,
    quantity INT,
    PRIMARY KEY (warehouse,product,model)
);
Code language: SQL (Structured Query Language) (sql)

次に、inventory テーブルにデータを挿入します。

INSERT INTO inventory(warehouse, product, model, quantity)
VALUES('San Jose', 'iPhone','6s',100);
INSERT INTO inventory(warehouse, product, model, quantity)
VALUES('San Fransisco', 'iPhone','6s',50);
INSERT INTO inventory(warehouse, product, model, quantity)
VALUES('San Jose','iPhone','7',50);
INSERT INTO inventory(warehouse, product, model, quantity)
VALUES('San Fransisco', 'iPhone','7',10);
INSERT INTO inventory(warehouse, product, model, quantity)
VALUES('San Jose','iPhone','X',150);
INSERT INTO inventory(warehouse, product, model, quantity)
VALUES('San Fransisco', 'iPhone','X',200);
INSERT INTO inventory(warehouse, product, model, quantity)
VALUES('San Jose','Samsung','Galaxy S',200);
INSERT INTO inventory(warehouse, product, model, quantity)
VALUES('San Fransisco','Samsung','Galaxy S',200);
INSERT INTO inventory(warehouse, product, model, quantity)
VALUES('San Fransisco','Samsung','Note 8',100);
INSERT INTO inventory(warehouse, product, model, quantity)
VALUES('San Jose','Samsung','Note 8',150);Code language: JavaScript (javascript)

3 番目に、inventory テーブルからデータをクエリします。

SELECT 
    *
FROM
    inventory;
Code language: SQL (Structured Query Language) (sql)

SQL GROUPING SETS - sample data

SQL GROUPING SETS の概要

グルーピングセットとは、GROUP BY 句を使用してグループ化する列のセットです。通常、単一の集約クエリは単一のグルーピングセットを定義します。

次の例では、グルーピングセット (warehouse, product) を定義しています。これは、倉庫と製品別に在庫に保管されている在庫管理単位 (SKU) の数を返します。

SELECT
    warehouse,
    product, 
    SUM (quantity) qty
FROM
    inventory
GROUP BY
    warehouse,
    product;
Code language: SQL (Structured Query Language) (sql)
SQL GROUPING SETS - inventory by warehouse and product

次のクエリは、倉庫別に SKU の数を検索します。これは、グルーピングセット (warehouse) を定義します。

SELECT
    warehouse, 
    SUM (quantity) qty
FROM
    inventory
GROUP BY
    warehouse;
Code language: SQL (Structured Query Language) (sql)
SQL GROUPING SETS - inventory by warehouse

次のクエリは、製品別に SKU の数を返します。これは、グルーピングセット (product) を定義します。

SELECT
    product, 
    SUM (quantity) qty
FROM
    inventory
GROUP BY
    product;
Code language: SQL (Structured Query Language) (sql)
SQL GROUPING SETS - inventory by product

次のクエリは、すべての倉庫と製品の SKU の数を検索します。これは、空のグルーピングセット () を定義します。

SELECT
    SUM(quantity) qty
FROM
    inventory;
Code language: SQL (Structured Query Language) (sql)
SQL GROUPING SETS - all inventory

これまでに、(warehouse, product)、(warehouse)、(product)、および () の 4 つのグルーピングセットがありました。単一のクエリを使用してすべてのグルーピングセットを返すには、UNION ALL 演算子を使用して上記のすべてのクエリを結合できます。

UNION ALL では、すべての結果セットの列数が同じである必要があるため、以下に示すように、各クエリの選択リストに NULL を追加する必要があります。

SELECT
    warehouse,
    product, 
    SUM (quantity) qty
FROM
    inventory
GROUP BY
    warehouse,
    product
UNION ALL
SELECT
    warehouse, 
    null,
    SUM (quantity) qty
FROM
    inventory
GROUP BY
    warehouse
UNION ALL
SELECT
    null,
    product, 
    SUM (quantity) qty
FROM
    inventory
GROUP BY
    product
UNION ALL
SELECT
    null,
    null,
    SUM(quantity) qty
FROM
    inventory;
Code language: SQL (Structured Query Language) (sql)

出力は次のとおりです。

SQL GROUPING SETS - UNION ALL

出力から明確にわかるように、クエリはすべてのグルーピングセットの集計を含む単一の結果セットを生成しました。

クエリは期待どおりに機能しますが、主に 2 つの問題があります。

  • まず、クエリが長いため、読みづらいです。
  • 次に、データベースシステムが在庫テーブルを複数回スキャンする必要があるため、パフォーマンスの問題があります。

これらの問題を解決するために、SQL は GROUPING SETS を提供します。

GROUPING SETS は、GROUP BY 句のオプションです。 GROUPING SETS は、同じクエリ内で複数のグルーピングセットを定義します。

GROUPING SETS オプションの一般的な構文を以下に示します。

SELECT
    c1,
    c2,
    aggregate (c3)
FROM
    table
GROUP BY
    GROUPING SETS (
        (c1, c2),
        (c1),
        (c2),
        ()
);
Code language: SQL (Structured Query Language) (sql)

このクエリは、4 つのグルーピングセット (c1,c2)、(c1)、(c2)、および () を定義します。

GROUPING SETS を適用して、上記の UNION ALL 句を含むクエリを書き直すことができます。

SELECT
    warehouse,
    product, 
    SUM (quantity) qty
FROM
    inventory
GROUP BY
    GROUPING SETS(
        (warehouse,product),
        (warehouse),
        (product),
        ()
    );Code language: SQL (Structured Query Language) (sql)

出力は次のとおりです。

SQL GROUPING SETS example

このクエリは、データベースシステムが inventory テーブルを複数回読み取る必要がないため、上記のクエリよりも読みやすく、実行速度が速くなります。

これで、SQL GROUPING SETS を使用して、単一のクエリで複数のグルーピングセットを生成する方法がわかるはずです。

このチュートリアルは役に立ちましたか?