GROUPING SETS
A grouping set is a set of columns by which you group by using the
GROUP BY
clause. A grouping set is denoted by a comma-separated list of columns placed inside parantheses (column1, column2, …)
Example of using grouping set
SELECT brand, segment, SUM (quantity)
FROM sales
GROUP BY brand, segment;
- It has a grouping set of the brand and segment (
(brand, segment)
)
GROUPING SETS
PostgreSQL has a performance issue when a table is scanned separately for multiple times.
To eliviate this issue, we can use GROUPING SETS
which is the subclause of the GROUP BY
clause.
The
GROUPING SETS
allows you to define multiple grouping sets in the same query.
# It has 4 grouping sets
SELECT c1, c2, aggregate_function(c3)
FROM table_name
GROUP BY
GROUPING SETS (
(c1, c2),
(c1),
(c2),
()
)
This is equivalent to the following:
SELECT c1, c2, aggregate_functions(c3)
FROM table_name
GROUP BY c1, c2
UNION ALL
SELECT c1, NULL, aggregate_function(c3)
FROM table_name
GROUP BY c1
UNION ALL
SELECT NULL, c2, aggregate_function(c3)
FROM table_name
GROUP BY c2
UNION ALL
SELECT NULL, NULL, SUM(c3)
FROM sales;
The query with GROUPING SETS
is much shorter and more readable. Not only that, PostgreSQL will optimize the number times
it scans the table.
GROUPING function
CASE
The CASE
expression is like if/else
statements, it allows us to have if-else logic to the query.
CASE
can be used anywhere such as SELECT
, WHERE
, GROUP BY
, HAVING
, etc.
General CASE
SELECT title,
length,
CASE
# if length is less than 50 minutes, the film is short
WHEN length > 0
AND length <= 50 THEN 'Short'
# if length is greater than 50 minutes and less than or equal to 120 minutes, the film is medium
WHEN length > 50
AND length <= 120 THEN 'Medium'
# if length is greater than 120 minutes, the film is long
WHEN length > 120 THEN 'Long'
END duration
FROM film
ORDER BY title;
- We can also use
CASE
expression with aggreagate function
# This shows the number of films that belong to economy, mass, and premium
SELECT
SUM (CASE
WHEN rental_rate = 0.99 THEN 1
ELSE 0
END
) AS "Economy",
SUM (CASE
WHEN rental_rate = 2.99 THEN 1
ELSE 0
END
) AS "Mass",
SUM (CASE
WHEN rental_rate = 4.99 THEN 1
ELSE 0
END
) AS "Premium"
FROM film;
Simple CASE
expression
SELECT title,
rating
CASE rating
WHEN 'G' THEN 'General Audiences'
WHEN 'PG' THEN 'Parental Guidance Suggested'
WHEN 'PG-13' THEN 'Parents Strongly Cautioned'
WHEN 'R' THEN 'Restricted'
WHEN 'NC-17' THEN 'Adults Only'
END rating_description
FROM film
ORDER BY title;
Example of simple expression with aggreate function
SELECT
SUM(CASE rating
WHEN 'G' THEN 1
ELSE 0
END) "General Audiences",
SUM(CASE rating
WHEN 'PG' THEN 1
ELSE 0
END) "Parental Guideance Suggested",
SUM(CASE rating
WHEN 'PG-13' THEN 1
ELSE 0
END) "Parents Strongly Cautioned",
SUM(CASE rating
WHEN 'R' THEN 1
ELSE 0
END) "Restricted",
SUM(CASE rating
WHEN 'NC-17' THEN 1
ELSE 0
END) "Adults Only"
FROM film;