MENU
Aggregate
Aggregate functions summarize a group of rows — the whole result set, or each group formed by GROUP BY — into a single value per group.Core Aggregates
- COUNT([DISTINCT] expr) returns the number of values retrieved.
- MAX([DISTINCT] expr) returns the maximum value retrieved.
- MIN([DISTINCT] expr) returns the minimum value retrieved.
- SUM([DISTINCT] expr) returns the sum of the values retrieved.
- AVG([DISTINCT] expr) returns the average of the values retrieved.
- GROUP_CONCAT([DISTINCT] expr [ORDER BY ...] [SEPARATOR str]) returns a string that is the concatenation of the retrieved values.
| SELECT COUNT(*) FROM tbl; SELECT id, email, COUNT(*) FROM User GROUP BY id, email HAVING COUNT(*)>1; SELECT COUNT(DISTINCT program_name) AS Count, program_type FROM cm_production WHERE push_number=@push_number GROUP BY program_type; SELECT a FROM tbl GROUP BY a HAVING MAX(b)>9; SELECT id, MAX(score) FROM Test GROUP BY id; |
| SELECT article, dealer, price FROM shop s1 WHERE price=(SELECT MAX(s2.price) FROM shop s2 WHERE s1.article = s2.article) ORDER BY article; |
| SELECT GROUP_CONCAT(DISTINCT score SEPARATOR ' ') FROM class GROUP BY student; |
WHERE vs. HAVING
WHERE filters rows based on a condition and is applied before any aggregate function is calculated. HAVING filters the results of a query based on a condition that may involve an aggregate function, and is applied after aggregation. Execution conceptually proceeds:- filter rows with WHERE
- aggregate rows into groups with GROUP BY
- filter groups with HAVING
| SELECT customer_id, SUM(total_amount) AS total_orders FROM orders WHERE order_date >= '2022-01-01' GROUP BY customer_id HAVING SUM(total_amount) > 500; |
CREATE TABLE orders (
customer_id INT,
order_date DATE,
total_amount DECIMAL(10,2)
);
INSERT INTO orders VALUES
(1, '2022-03-01', 300.00),
(1, '2022-06-15', 250.00),
(2, '2022-02-10', 100.00);
-- WHERE filters rows, GROUP BY aggregates, HAVING filters the aggregates
SELECT customer_id, SUM(total_amount) AS total_orders
FROM orders
WHERE order_date >= '2022-01-01'
GROUP BY customer_id
HAVING SUM(total_amount) > 500;| customer_id | total_orders |
|---|---|
| 1 | 550.00 |
Aggregating into JSON
Rows can also be aggregated directly into a JSON array or object; see JSON for the scalar JSON functions.| SELECT o_id, JSON_ARRAYAGG(attribute) AS attributes FROM t3 GROUP BY o_id; |
For a t3 table with rows (o_id=2,attribute='color'), (o_id=2,attribute='fabric'), (o_id=3,attribute='color'), (o_id=3,attribute='shape'), this produces o_id=2 → ["color","fabric"] and o_id=3 → ["color","shape"].
| SELECT o_id, JSON_OBJECTAGG(attribute, value) FROM t3 GROUP BY o_id; |
For the same rows plus a value column ('red','silk','green', 'square'), this produces o_id=2 → {"color":"red","fabric":"silk"} and o_id=3 → {"color":"green","shape":"square"}.
CREATE TABLE t3 (o_id INT, attribute VARCHAR(20), value VARCHAR(20));
INSERT INTO t3 VALUES
(2, 'color', 'red'), (2, 'fabric', 'silk'),
(3, 'color', 'green'), (3, 'shape', 'square');
SELECT o_id, JSON_ARRAYAGG(attribute) AS attributes
FROM t3 GROUP BY o_id;
SELECT o_id, JSON_OBJECTAGG(attribute, value)
FROM t3 GROUP BY o_id;SELECT o_id, JSON_ARRAYAGG(attribute) AS attributes FROM t3 GROUP BY o_id:
SELECT o_id, JSON_OBJECTAGG(attribute, value) FROM t3 GROUP BY o_id:
| o_id | attributes |
|---|---|
| 2 | ["color", "fabric"] |
| 3 | ["color", "shape"] |
| o_id | JSON_OBJECTAGG(attribute, value) |
|---|---|
| 2 | {"color": "red", "fabric": "silk"} |
| 3 | {"color": "green", "shape": "square"} |