SQL教學
SQL RDBMS概念
SQL簡介
SQL NOT NULL約束
SQL DEFAULT約束
SQL唯一約束
SQL主鍵
SQL外鍵
SQL CHECK約束
SQL示例數據庫
SQL索引約束
SQL NULL值
數據庫 - 第一範式(1NF)
數據庫 - 第二範式(2NF)
數據庫 - 第三範式(3NF)
SQL RDBMS數據庫
SQL語法
SQL數據類型
SQL操運算符
SQL算術運算符
SQL比較運算符
SQL邏輯運算符
SQL表達式
SQL創建數據庫(CREATE DATABASE)
SQL丟棄或刪除數據庫(DROP DATABASE)
SQL選擇數據庫(SELECT Database, USE語句)
SQL創建表(CREATE Table)
SQL從現有表創建表
SQL刪除表(DROP或DELETE Table)
SQL INSERT INTO插入查詢
SQL SELECT查詢語句
SQL WHERE子句
SQL AND和OR運算符
SQL UPDATE更新查詢
SQL DELETE刪除查詢
SQL LIKE子句
SQL TOP,LIMIT,ROWNUM子句
SQL ORDER BY排序子句
SQL GROUP BY(分組)
SQL Distinct關鍵字
SQL排序結果
SQL約束
SQL Join聯接
SQL INNER JOIN(內部連接)
SQL LEFT JOIN(左連接)
SQL RIGHT JOIN(右連接)
SQL FULL JOIN(全連接)
SQL自連接
SQL笛卡爾或交叉連接
SQL UNION子句/操作符
SQL INTERSECT子句
SQL EXCEPT子句
SQL別名語法
SQL索引
SQL ALTER TABLE(修改表)
SQL TRUNCATE TABLE(截斷表)
SQL View(視圖)
SQL Having子句
SQL事務
SQL通配符運算符
SQL日期函數
SQL ADDDATE()函數
SQL ADDTIME()函數
SQL CONVERT_TZ()函數
SQL CURDATE()函數
SQL CURRENT_DATE()函數
SQL CURTIME()函數
SQL CURRENT_TIME()函數
SQL CURRENT_TIMESTAMP()方法
SQL DATE(expr)函數
SQL DATEDIFF()方法
SQL DATE_ADD()和DATE_SUB()方法
SQL DATE_FORMAT()函數
SQL DATE_SUB()方法
SQL DAY()函數
SQL DAYNAME()函數
SQL DAYOFMONTH()函數
SQL DAYOFWEEK()函數
SQL DAYOFYEAR()函數
SQL EXTRACT()函數
SQL FROM_DAYS()函數
SQL FROM_UNIXTIME()函數
SQL HOUR()方法
SQL LAST_DAY()函數
SQL LOCALTIME和LOCALTIME()函數
SQL LOCALTIMESTAMP和LOCALTIMESTAMP()函數
SQL MAKEDATE()函數
SQL MAKETIME()函數
SQL MICROSECOND()函數
SQL MINUTE()函數
SQL MONTH()函數
SQL MONTHNAME()函數
SQL NOW()函數
SQL PERIOD_ADD()函數
SQL PERIOD_DIFF()函數
SQL QUARTER()函數
SQL SECOND()函數
SQL SEC_TO_TIME()函數
SQL STR_TO_DATE()函數
SQL SUBDATE()函數
SQL SUBTIME()函數
SQL SYSDATE()函數
SQL TIME()函數
SQL TIMEDIFF()函數
SQL TIMESTAMP()函數
SQL TIMESTAMPADD()函數
SQL TIMESTAMPDIFF()函數
SQL TIME_FORMAT()函數
SQL TIME_TO_SEC()函數
SQL TO_DAYS()函數
SQL UNIX_TIMESTAMP()函數
SQL UTC_DATE()函數
SQL UTC_TIME()函數
SQL UTC_TIMESTAMP()函數
SQL WEEK()函數
SQL WEEKDAY()函數
SQL WEEKOFYEAR()函數
SQL YEAR()函數
SQL YEARWEEK()函數
SQL臨時表
SQL克隆表
SQL子查詢
SQL使用序列(自動遞增)
SQL DISTINCT重複處理
SQL注入
SQL實用函數
SQL MAX()函數
SQL MIN()函數
SQL AVG()函數
SQL SUM()函數
SQL SQRT()函數
SQL RAND()函數
SQL CONCAT()函數
SQL數值函數
SQL ABS()函數
SQL ACOS()函數
SQL ASIN(X)函數
SQL ATAN(X)函數
SQL ATAN2()函數
SQL BIT_AND()函數
SQL BIT_COUNT()函數
SQL BIT_OR()函數
SQL CEIL()函數
SQL CONV()函數
SQL COS()函數
SQL COT()函數
SQL DEGREES()函數
SQL EXP(X)函數
SQL FLOOR(X)函數
SQL FORMAT(X,D)函數
SQL GREATEST()函數
SQL INTERVAL()函數
SQL LEAST()函數
SQL LOG()函數
SQL LOG10(X)函數
SQL MOD()函數
SQL OCT(N)函數
SQL PI()函數
SQL POW()函數
SQL RADIANS()函數
SQL ROUND()函數
SQL SIGN(X)函數
SQL SIN(X)函數
SQL SQRT(X)函數
SQL STD()函數
SQL TAN(X)函數
SQL TRUNCATE()函數
SQL字符串函數
SQL ASCII(str)函數
SQL BIN(N)函數
SQL BIT_LENGTH()函數
SQL CHAR()函數
SQL CHAR_LENGTH()函數
SQL CHARACTER_LENGTH()函數
SQL字符串CONCAT()函數
SQL CONCAT_WS()函數
SQL CONV(N,from_base,to_base)函數
SQL ELT()函數
SQL EXPORT_SET()函數
SQL FIELD()函數
SQL FIND_IN_SET()函數
SQL FORMAT()函數
SQL HEX()函數
SQL INSERT()函數
SQL INSTR()函數
SQL LCASE()函數
SQL LEFT()函數
SQL LENGTH()函數
SQL LOAD_FILE()函數
SQL LOCATE()函數
SQL LOWER()函數
SQL LPAD()函數
SQL LTRIM()函數
SQL MAKE_SET()函數
SQL MID()函數
SQL OCT()函數
SQL OCTET_LENGTH()函數
SQL ORD()函數
SQL POSITION()函數
SQL QUOTE()函數
SQL REGEXP模式
SQL REPEAT()函數
SQL REPLACE()函數
SQL REVERSE()函數
SQL RIGHT()函數
SQL RPAD()函數
SQL SOUNDEX()函數
SQL SPACE()函數
SQL STRCMP()函數
SQL SUBSTRING()函數
SQL SUBSTRING_INDEX()函數
SQL TRIM()函數
SQL UCASE()函數
SQL UNHEX()函數
SQL UPPER()函數

SQL Grouping Sets運算符

在本教程中,您將學習如何使用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

1. SQL GROUPING SETS簡介

分組集是一組使用GROUP BY子句進行分組的列。 通常,單個聚合查詢定義單個分組集。

以下示例定義分組集(倉庫,產品)。 它返回倉庫和產品中存儲在庫存中的庫存單位數(SKU)。

SELECT
    warehouse,
    product, 
    SUM(quantity) qty
FROM
    inventory
GROUP BY
    warehouse,
    product;

執行上面查詢語句,得到以下結果:

SQL

以下查詢查找倉庫的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 SETSGROUP 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使用單個查詢生成多個分組集。