在本教學中,您將學習如何使用SQL GROUPING SETS
運算子生成多個分組集。
建立樣本表
讓我們建立一個名為inventory
的新錶來演示GROUPING SETS
的功能。
首先,建立一個名為inventory
的新表:
CREATE TABLE inventory (
warehouse VARCHAR(255),
product VARCHAR(255) NOT NULL,
model VARCHAR(50) NOT NULL,
quantity INT,
PRIMARY KEY (warehouse,product,model)
);
第二步,將資料插入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);
第三,查詢inventory
表中的資料:
SELECT
*
FROM
inventory;
+---------------+---------+----------+----------+
| warehouse | product | model | quantity |
+---------------+---------+----------+----------+
| San Jose | iPhone | 6s | 100 |
| San Fransisco | iPhone | 6s | 50 |
| San Jose | iPhone | 7 | 50 |
| San Fransisco | iPhone | 7 | 10 |
| San Jose | iPhone | X | 150 |
| San Fransisco | iPhone | X | 200 |
| San Jose | Samsung | Galaxy S | 200 |
| San Fransisco | Samsung | Galaxy S | 200 |
| San Fransisco | Samsung | Note 8 | 100 |
| San Jose | Samsung | Note 8 | 150 |
+---------------+---------+----------+----------+
10 rows in set
分組集是一組使用GROUP BY
子句進行分組的列。 通常,單個聚合查詢定義單個分組集。
以下範例定義分組集(倉庫,產品)。 它返回倉庫和產品中儲存在庫存中的庫存單位數(SKU)。
SELECT
warehouse,
product,
SUM(quantity) qty
FROM
inventory
GROUP BY
warehouse,
product;
執行上面查詢語句,得到以下結果:
以下查詢查詢倉庫的SKU數量。 它定義了分組集(warehouse
):
SELECT
warehouse,
SUM(quantity) qty
FROM
inventory
GROUP BY
warehouse;
+---------------+-----+
| warehouse | qty |
+---------------+-----+
| San Fransisco | 560 |
| San Jose | 650 |
+---------------+-----+
2 rows in set
以下查詢返回產品的SKU數。 它定義了分組集(product
):
SELECT
product,
SUM(quantity) qty
FROM
inventory
GROUP BY
product;
執行上面查詢語句,得到以下結果:
+---------+-----+
| product | qty |
+---------+-----+
| iPhone | 560 |
| Samsung | 650 |
+---------+-----+
2 rows in set
以下查詢查詢所有倉庫和產品的SKU數。 它定義了一個空的分組集()
。
SELECT
SUM(quantity) qty
FROM
inventory;
執行上面範例程式碼,得到以下結果:
+------+
| qty |
+------+
| 1210 |
+------+
1 row in set
到目前為止,我們有四個分組集:(warehouse
, product
),(warehouse
),(product
)和()
。 要使用單個查詢返回所有分組集,可以使用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;
執行上面查詢語句,得到以下結果 -
+---------------+---------+------+
| warehouse | product | qty |
+---------------+---------+------+
| San Fransisco | iPhone | 260 |
| San Fransisco | Samsung | 300 |
| San Jose | iPhone | 300 |
| San Jose | Samsung | 350 |
| San Fransisco | NULL | 560 |
| San Jose | NULL | 650 |
| NULL | iPhone | 560 |
| NULL | Samsung | 650 |
| NULL | NULL | 1210 |
+---------------+---------+------+
9 rows in set
從輸出中可以清楚地看到,查詢生成了一個結果集,其中包含所有分組集的聚合。儘管查詢按預期工作,但它有兩個主要問題:
為解決這些問題,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),
()
);
此查詢定義了四個分組集(c1,c2)
,(c1)
,(c2)
和()
。可以使用GROUPING SETS
將上面的UNION ALL
子句查詢重寫:
SELECT
warehouse,
product,
SUM (quantity) qty
FROM
inventory
GROUP BY
GROUPING SETS(
(warehouse,product),
(warehouse),
(product),
()
);
執行上面查詢語句,得到以下結果:
+---------------+---------+------+
| warehouse | product | qty |
+---------------+---------+------+
| San Fransisco | iPhone | 260 |
| San Fransisco | Samsung | 300 |
| San Jose | iPhone | 300 |
| San Jose | Samsung | 350 |
| San Fransisco | NULL | 560 |
| San Jose | NULL | 650 |
| NULL | iPhone | 560 |
| NULL | Samsung | 650 |
| NULL | NULL | 1210 |
+---------------+---------+------+
9 rows in set
此查詢比上面的查詢更具可讀性和執行速度,因為資料庫系統不必多次讀取庫存表。
現在,應該知道如何使用SQL GROUPING SETS
使用單個查詢生成多個分組集。