Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

GROUP BY nhiều cột trong MySQL với IF()

Sử dụng IF() hoặc CASE WHEN trong SELECT kết hợp GROUP BY nhiều cột để tạo cột flag chỉ thị điều kiện.

Cú pháp

SELECT cột_nhóm1, cột_nhóm2, IF(điều_kiện, 1, 0) AS flag
FROM tên_bảng
GROUP BY cột_nhóm1, cột_nhóm2;

Ví dụ minh họa

Tạo bảng đơn hàng:

mysql> CREATE TABLE MultipleGroupByDemo (
    -> Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    -> CustomerId INT,
    -> ProductName VARCHAR(100)
    -> );
Query OK, 0 rows affected (0.59 sec)

Chèn dữ liệu:

mysql> INSERT INTO MultipleGroupByDemo(CustomerId, ProductName) VALUES
    -> (1000, 'Product-1'), (1001, 'Product-2'), (1001, 'Product-2'), (1001, 'Product-2'),
    -> (1002, 'Product-3'), (1002, 'Product-3'), (1003, 'Product-4');

Xem dữ liệu:

mysql> SELECT * FROM MultipleGroupByDemo;
+----+------------+-------------+
| Id | CustomerId | ProductName |
+----+------------+-------------+
| 1  | 1000       | Product-1   |
| 2  | 1001       | Product-2   |
| 3  | 1001       | Product-2   |
| 4  | 1001       | Product-2   |
| 5  | 1002       | Product-3   |
| 6  | 1002       | Product-3   |
| 7  | 1003       | Product-4   |
+----+------------+-------------+

GROUP BY ProductName, CustomerId với flag Product-2:

mysql> SELECT CustomerId, IF(ProductName = 'Product-2', 1, 0)
    -> FROM MultipleGroupByDemo
    -> GROUP BY ProductName, CustomerId;
+------------+---------------------------------------+
| CustomerId | if(ProductName = 'Product-2', 1, 0)   |
+------------+---------------------------------------+
| 1000       | 0                                     |
| 1001       | 1                                     |
| 1002       | 0                                     |
| 1003       | 0                                     |

Cách viết chuẩn hơn: MAX(IF()) với GROUP BY đơn

mysql> SELECT CustomerId, MAX(IF(ProductName = 'Product-2', 1, 0))
    -> FROM MultipleGroupByDemo
    -> GROUP BY CustomerId;
+------------+-----------------------------------------+
| CustomerId | MAX(IF(ProductName = 'Product-2', 1, 0)) |
+------------+-----------------------------------------+
| 1000       | 0                                       |
| 1001       | 1                                       |
| 1002       | 0                                       |
| 1003       | 0                                       |
+------------+-----------------------------------------+

Cách này nhóm theo CustomerId, kiểm tra xem khách hàng đó có mua Product-2 không (1=có, 0=không).

Mở rộng: Pivot table (cột động)

SELECT CustomerId,
       MAX(IF(ProductName = 'Product-1', 1, 0)) AS `Product-1`,
       MAX(IF(ProductName = 'Product-2', 1, 0)) AS `Product-2`,
       MAX(IF(ProductName = 'Product-3', 1, 0)) AS `Product-3`,
       MAX(IF(ProductName = 'Product-4', 1, 0)) AS `Product-4`
FROM MultipleGroupByDemo
GROUP BY CustomerId;
+------------+-----------+-----------+-----------+-----------+
| CustomerId | Product-1 | Product-2 | Product-3 | Product-4 |
+------------+-----------+-----------+-----------+-----------+
| 1000       | 1         | 0         | 0         | 0         |
| 1001       | 0         | 1         | 0         | 0         |
| 1002       | 0         | 0         | 1         | 0         |
| 1003       | 0         | 0         | 0         | 1         |
+------------+-----------+-----------+-----------+-----------+

MySQL 8.0+: CTE + Window Function

WITH ranked AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY CustomerId, ProductName ORDER BY Id) AS rn
    FROM MultipleGroupByDemo
)
SELECT CustomerId, ProductName FROM ranked WHERE rn = 1;