We continue to get acquainted with new features in PostgreSQL 9.5.
Part 1. INSERT ... ON CONFLICT DO NOTHING / UPDATE and ROW LEVEL SECURITYPart 2. TABLESAMPLEToday we consider multiple groups in one query. This feature was described in the SQL-99 standard. It is convenient to use it if you need to make several queries to the same table, differing only in the 
GROUP BY clause . For this, 
GROUPING SETS, ROLLUP, CUBE modifiers are specified as a grouping element after the 
GROUP BY keyword.
Let's take a closer look at how this works.
Suppose we have a scheme in which there is data on payments, each payment has a type, a city in which this payment was made and the amount of the payment. The city necessarily has a country and, optionally, a region. Below are the requests to create such a scheme and fill it with data.
Creating a schemaDROP TABLE IF EXISTS payment; DROP TABLE IF EXISTS payment_type; DROP TABLE IF EXISTS city; DROP TABLE IF EXISTS state; DROP TABLE IF EXISTS country; CREATE TABLE country ( id SERIAL PRIMARY KEY, name VARCHAR NOT NULL ); CREATE TABLE state ( id SERIAL PRIMARY KEY, name VARCHAR NOT NULL, country_id INT REFERENCES country (id) ); CREATE TABLE city ( id SERIAL PRIMARY KEY, name VARCHAR NOT NULL, state_id INT NULL REFERENCES state (id), country_id INT NOT NULL REFERENCES country (id), population BIGINT NOT NULL ); CREATE TABLE payment_type ( id SERIAL PRIMARY KEY, name VARCHAR NOT NULL ); CREATE TABLE payment ( id BIGSERIAL PRIMARY KEY, payment_type_id INT NOT NULL REFERENCES payment_type (id), city_id INT NOT NULL REFERENCES city (id), amount NUMERIC(10, 2) NOT NULL ); INSERT INTO country (name) VALUES ('Russia'), ('Ukraine'); INSERT INTO state (name, country_id) VALUES ('Moscow region', 1), ('Samara region', 1), ('Kursk region', 1), ('Tatarstan', 1), ('Kiev region', 2), ('Lugansk region', 2), ('Lvov region', 2), ('Odessa region', 2); –-          ,      INSERT INTO city (name, state_id, country_id, population) VALUES ('Moscow', NULL, 1, 12197596), ('Dubna', 1, 1, 75176), ('Samara', 2, 1, 1171820), ('Tolyatti', 2, 1, 719646), ('Syzran', 2, 1, 175222), ('Novokuybyshevsk', 2, 1, 105007), ('Kursk', 3, 1, 435117), ('Kazan', 4, 1, 1205651), ('Kiev', NULL, 2, 2888470), ('Irpen', 5, 2, 39972), ('Borispol', 5, 2, 60102), ('Belaya Tserkov', 5, 2, 211205), ('Lugansk', 6, 2, 417990), ('Lisichansk', 6, 2, 103459), ('Severodonetsk', 6, 2, 108899), ('Popasnaya', 6, 2, 21765), ('Lvov', 7, 2, 729038), ('Drogobych', 7, 2, 76866), ('Odessa', 8, 2, 1017022), ('Izmail', 8, 2, 72501); INSERT INTO payment_type (name) VALUES ('Online'), ('Box office'), ('Terminal'); INSERT INTO payment (payment_type_id, city_id, amount) SELECT ceil(random() * 3), ceil(random() * 20), trunc(cast(random() * 10000 AS NUMERIC), 2) FROM generate_series(1, 10000); 
 Suppose we want to get statistics on the amount of payments in each city and in each country. Previously, it was necessary to write a query of the form:
 (SELECT sum(amount), c.country_id, NULL as city_id FROM payment AS p INNER JOIN city AS c ON p.city_id=c.id GROUP BY c.country_id ORDER BY c.country_id) UNION ALL (SELECT sum(amount), NULL, p.city_id FROM payment AS p GROUP BY p.city_id ORDER BY p.city_id) 
Query result| sum | country_id | city_id | 
|---|
| 19794121.93 | one | Null | 
| 30138426.57 | 2 | Null | 
| 2420939.72 | Null | one | 
| 2611787.51 | Null | 2 | 
| 2357570.54 | Null | 3 | 
| 2796471.48 | Null | four | 
| 2327588.11 | Null | five | 
| 2563701.69 | Null | 6 | 
| 2442654.38 | Null | 7 | 
| 2273408.5 | Null | eight | 
| 2509228.24 | Null | 9 | 
| 2716771.77 | Null | ten | 
| 2745394.99 | Null | eleven | 
| 2554721.34 | Null | 12 | 
| 2526112.36 | Null | 13 | 
| 2818708.34 | Null | 14 | 
| 2437768.84 | Null | 15 | 
| 2246483.68 | Null | sixteen | 
| 2384795.14 | Null | 17 | 
| 2437849.05 | Null | 18 | 
| 2470876.07 | Null | nineteen | 
| 2289716.75 | Null | 20 | 
 From version 9.5 it is easier to write a similar request like this:
 SELECT sum(amount), c.country_id, p.city_id FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY GROUPING SETS(c.country_id, p.city_id); 
Query result| sum | country_id | city_id | 
|---|
| 19794121.93 | one | Null | 
| 30138426.57 | 2 | Null | 
| 2420939.72 | Null | one | 
| 2611787.51 | Null | 2 | 
| 2357570.54 | Null | 3 | 
| 2796471.48 | Null | four | 
| 2327588.11 | Null | five | 
| 2563701.69 | Null | 6 | 
| 2442654.38 | Null | 7 | 
| 2273408.5 | Null | eight | 
| 2509228.24 | Null | 9 | 
| 2716771.77 | Null | ten | 
| 2745394.99 | Null | eleven | 
| 2554721.34 | Null | 12 | 
| 2526112.36 | Null | 13 | 
| 2818708.34 | Null | 14 | 
| 2437768.84 | Null | 15 | 
| 2246483.68 | Null | sixteen | 
| 2384795.14 | Null | 17 | 
| 2437849.05 | Null | 18 | 
| 2470876.07 | Null | nineteen | 
| 2289716.75 | Null | 20 | 
 As you can see, the 
GROUPING SETS as a result of the query returns data as follows: in each row of one of the columns listed in brackets corresponds to the value, while the remaining columns (from the list in brackets) are filled with NULL. Columns not listed in 
GROUPING SETS are calculated as usual.
To get the full amount (without grouping), you can use the empty grouping - 
() . With empty grouping, all fields participating in 
GROUPING SETS are NULL:
 SELECT sum(amount), p.city_id, c.country_id FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY GROUPING SETS(p.city_id, C.country_id, ()); 
Query result| sum | country_id | city_id | 
|---|
| 19794121.93 | one | Null | 
| 30138426.57 | 2 | Null | 
| 49932548.5 | Null | Null | 
| 2420939.72 | Null | one | 
| 2611787.51 | Null | 2 | 
| 2357570.54 | Null | 3 | 
| 2796471.48 | Null | four | 
| 2327588.11 | Null | five | 
| 2563701.69 | Null | 6 | 
| 2442654.38 | Null | 7 | 
| 2273408.5 | Null | eight | 
| 2509228.24 | Null | 9 | 
| 2716771.77 | Null | ten | 
| 2745394.99 | Null | eleven | 
| 2554721.34 | Null | 12 | 
| 2526112.36 | Null | 13 | 
| 2818708.34 | Null | 14 | 
| 2437768.84 | Null | 15 | 
| 2246483.68 | Null | sixteen | 
| 2384795.14 | Null | 17 | 
| 2437849.05 | Null | 18 | 
| 2470876.07 | Null | nineteen | 
| 2289716.75 | Null | 20 | 
 Now let's try to get the amount of payments in the context of cities, regions and countries:
 SELECT sum(amount), p.city_id, c.state_id, c.country_id FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY GROUPING SETS(p.city_id, c.state_id, c.country_id); 
Query result| sum | city_id | state_id | country_id | 
|---|
| 2420939.72 | one | Null | Null | 
| 2611787.51 | 2 | Null | Null | 
| 2357570.54 | 3 | Null | Null | 
| 2796471.48 | four | Null | Null | 
| 2327588.11 | five | Null | Null | 
| 2563701.69 | 6 | Null | Null | 
| 2442654.38 | 7 | Null | Null | 
| 2273408.5 | eight | Null | Null | 
| 2509228.24 | 9 | Null | Null | 
| 2716771.77 | ten | Null | Null | 
| 2745394.99 | eleven | Null | Null | 
| 2554721.34 | 12 | Null | Null | 
| 2526112.36 | 13 | Null | Null | 
| 2818708.34 | 14 | Null | Null | 
| 2437768.84 | 15 | Null | Null | 
| 2246483.68 | sixteen | Null | Null | 
| 2384795.14 | 17 | Null | Null | 
| 2437849.05 | 18 | Null | Null | 
| 2470876.07 | nineteen | Null | Null | 
| 2289716.75 | 20 | Null | Null | 
| 19794121.93 | Null | Null | one | 
| 30138426.57 | Null | Null | 2 | 
| 2611787.51 | Null | one | Null | 
| 10045331.82 | Null | 2 | Null | 
| 2442654.38 | Null | 3 | Null | 
| 2273408.5 | Null | four | Null | 
| 8016888.1 | Null | five | Null | 
| 10029073.22 | Null | 6 | Null | 
| 4822644.19 | Null | 7 | Null | 
| 4760592.82 | Null | eight | Null | 
| 4930167.96 | Null | Null | Null | 
 Strange, we did not make an empty grouping, but received a string in which all fields are NULL. In fact, this happened because the 
state_id field 
was not filled in in Moscow and Kiev, therefore 
GROUPING SETS rightly did the grouping by 
state_id = NULL . This is easily verified by running the following query:
 SELECT sum(amount) FROM payment WHERE city_id IN (1, 9); 
Yes, our assumption turned out to be true and the amounts coincided.
Well, where did this strange line come from, we figured it out, but how to distinguish in the next query, which of the lines 
contains the full amount, and which group is 
state_id = NULL ?
 SELECT sum(amount), p.city_id, c.state_id, c.country_id FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY GROUPING SETS(p.city_id, c.state_id, c.country_id, ()); 
Query result| sum | city_id | state_id | country_id | 
|---|
| 2420939.72 | one | Null | Null | 
| 2611787.51 | 2 | Null | Null | 
| 2357570.54 | 3 | Null | Null | 
| 2796471.48 | four | Null | Null | 
| 2327588.11 | five | Null | Null | 
| 2563701.69 | 6 | Null | Null | 
| 2442654.38 | 7 | Null | Null | 
| 2273408.5 | eight | Null | Null | 
| 2509228.24 | 9 | Null | Null | 
| 2716771.77 | ten | Null | Null | 
| 2745394.99 | eleven | Null | Null | 
| 2554721.34 | 12 | Null | Null | 
| 2526112.36 | 13 | Null | Null | 
| 2818708.34 | 14 | Null | Null | 
| 2437768.84 | 15 | Null | Null | 
| 2246483.68 | sixteen | Null | Null | 
| 2384795.14 | 17 | Null | Null | 
| 2437849.05 | 18 | Null | Null | 
| 2470876.07 | nineteen | Null | Null | 
| 2289716.75 | 20 | Null | Null | 
| 49932548.5 | Null | Null | Null | 
| 19794121.93 | Null | Null | one | 
| 30138426.57 | Null | Null | 2 | 
| 2611787.51 | Null | one | Null | 
| 10045331.82 | Null | 2 | Null | 
| 2442654.38 | Null | 3 | Null | 
| 2273408.5 | Null | four | Null | 
| 8016888.1 | Null | five | Null | 
| 10029073.22 | Null | 6 | Null | 
| 4822644.19 | Null | 7 | Null | 
| 4760592.82 | Null | eight | Null | 
| 4930167.96 | Null | Null | Null | 
 So in fact, the total value will be greater, you say, and you will be right. Of course, in this query, you can understand that the line with the larger amount is the full amount. However, if the table had not only positive values, but also negative ones, it would be more difficult to determine the full amount. Well, or if you use another aggregate function:
 SELECT avg(amount), p.city_id, c.state_id, c.country_id FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY GROUPING SETS(p.city_id, c.state_id, c.country_id, ()); 
Query result| avg | city_id | state_id | country_id | 
|---|
| 4841.87944 | one | Null | Null | 
| 5141.313996062992126 | 2 | Null | Null | 
| 4850.9681893004115226 | 3 | Null | Null | 
| 4958.2827659574468085 | four | Null | Null | 
| 4849.1418958333333333 | five | Null | Null | 
| 5096.8224453280318091 | 6 | Null | Null | 
| 5208.2182942430703625 | 7 | Null | Null | 
| 4985.5449561403508772 | eight | Null | Null | 
| 5038.6109236947791165 | 9 | Null | Null | 
| 5135.6744234404536862 | ten | Null | Null | 
| 5219.3821102661596958 | eleven | Null | Null | 
| 4903.4958541266794626 | 12 | Null | Null | 
| 5092.9684677419354839 | 13 | Null | Null | 
| 5006.5867495559502664 | 14 | Null | Null | 
| 4964.9059877800407332 | 15 | Null | Null | 
| 4992.1859555555555556 | sixteen | Null | Null | 
| 4694.4786220472440945 | 17 | Null | Null | 
| 5047.3065217391304348 | 18 | Null | Null | 
| 4883.1542885375494071 | nineteen | Null | Null | 
| 4945.392548596112311 | 20 | Null | Null | 
| 4993.25485 | Null | Null | Null | 
| 4990.9535879979828543 | Null | Null | one | 
| 4994.7674129930394432 | Null | Null | 2 | 
| 5141.313996062992126 | Null | one | Null | 
| 4941.1371470732907034 | Null | 2 | Null | 
| 5208.2182942430703625 | Null | 3 | Null | 
| 4985.5449561403508772 | Null | four | Null | 
| 5086.8579314720812183 | Null | five | Null | 
| 5014.53661 | Null | 6 | Null | 
| 4866.4421695257315843 | Null | 7 | Null | 
| 4912.8924871001031992 | Null | eight | Null | 
| 4940.0480561122244489 | Null | Null | Null | 
 Which line corresponds to the average amount of payment in the table, and which - the average amount in Kiev and Moscow?
Fortunately, there is a solution: the new 
grouping () function, with the help of it we can find out whether a particular column is participating in a given row in a grouping. If 
grouping (column_name) returns 0, then column_name participates in the grouping, if 1 - does not participate:
 SELECT avg(amount), p.city_id, c.state_id, c.country_id, grouping(c.state_id) FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY GROUPING SETS(p.city_id, c.state_id, c.country_id, ()); 
Query result| avg | city_id | state_id | country_id | grouping | 
|---|
| 4841.87944 | one | Null | Null | one | 
| 5141.313996062992126 | 2 | Null | Null | one | 
| 4850.9681893004115226 | 3 | Null | Null | one | 
| 4958.2827659574468085 | four | Null | Null | one | 
| 4849.1418958333333333 | five | Null | Null | one | 
| 5096.8224453280318091 | 6 | Null | Null | one | 
| 5208.2182942430703625 | 7 | Null | Null | one | 
| 4985.5449561403508772 | eight | Null | Null | one | 
| 5038.6109236947791165 | 9 | Null | Null | one | 
| 5135.6744234404536862 | ten | Null | Null | one | 
| 5219.3821102661596958 | eleven | Null | Null | one | 
| 4903.4958541266794626 | 12 | Null | Null | one | 
| 5092.9684677419354839 | 13 | Null | Null | one | 
| 5006.5867495559502664 | 14 | Null | Null | one | 
| 4964.9059877800407332 | 15 | Null | Null | one | 
| 4992.1859555555555556 | sixteen | Null | Null | one | 
| 4694.4786220472440945 | 17 | Null | Null | one | 
| 5047.3065217391304348 | 18 | Null | Null | one | 
| 4883.1542885375494071 | nineteen | Null | Null | one | 
| 4945.392548596112311 | 20 | Null | Null | one | 
| 4993.25485 | Null | Null | Null | one | 
| 4990.9535879979828543 | Null | Null | one | one | 
| 4994.7674129930394432 | Null | Null | 2 | one | 
| 5141.313996062992126 | Null | one | Null | 0 | 
| 4941.1371470732907034 | Null | 2 | Null | 0 | 
| 5208.2182942430703625 | Null | 3 | Null | 0 | 
| 4985.5449561403508772 | Null | four | Null | 0 | 
| 5086.8579314720812183 | Null | five | Null | 0 | 
| 5014.53661 | Null | 6 | Null | 0 | 
| 4866.4421695257315843 | Null | 7 | Null | 0 | 
| 4912.8924871001031992 | Null | eight | Null | 0 | 
| 4940.0480561122244489 | Null | Null | Null | 0 | 
 In fact, 
grouping returns a bitmask for the columns listed in it:
 SELECT avg(amount), p.city_id, c.state_id, c.country_id, grouping(p.city_id, c.state_id, c.country_id) FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY GROUPING SETS(p.city_id, c.state_id, c.country_id, ()); 
Query result| avg | city_id | state_id | country_id | grouping | 
|---|
| 4841.87944 | one | Null | Null | 3 | 
| 5141.313996062992126 | 2 | Null | Null | 3 | 
| 4850.9681893004115226 | 3 | Null | Null | 3 | 
| 4958.2827659574468085 | four | Null | Null | 3 | 
| 4849.1418958333333333 | five | Null | Null | 3 | 
| 5096.8224453280318091 | 6 | Null | Null | 3 | 
| 5208.2182942430703625 | 7 | Null | Null | 3 | 
| 4985.5449561403508772 | eight | Null | Null | 3 | 
| 5038.6109236947791165 | 9 | Null | Null | 3 | 
| 5135.6744234404536862 | ten | Null | Null | 3 | 
| 5219.3821102661596958 | eleven | Null | Null | 3 | 
| 4903.4958541266794626 | 12 | Null | Null | 3 | 
| 5092.9684677419354839 | 13 | Null | Null | 3 | 
| 5006.5867495559502664 | 14 | Null | Null | 3 | 
| 4964.9059877800407332 | 15 | Null | Null | 3 | 
| 4992.1859555555555556 | sixteen | Null | Null | 3 | 
| 4694.4786220472440945 | 17 | Null | Null | 3 | 
| 5047.3065217391304348 | 18 | Null | Null | 3 | 
| 4883.1542885375494071 | nineteen | Null | Null | 3 | 
| 4945.392548596112311 | 20 | Null | Null | 3 | 
| 4993.25485 | Null | Null | Null | 7 | 
| 4990.9535879979828543 | Null | Null | one | 6 | 
| 4994.7674129930394432 | Null | Null | 2 | 6 | 
| 5141.313996062992126 | Null | one | Null | five | 
| 4941.1371470732907034 | Null | 2 | Null | five | 
| 5208.2182942430703625 | Null | 3 | Null | five | 
| 4985.5449561403508772 | Null | four | Null | five | 
| 5086.8579314720812183 | Null | five | Null | five | 
| 5014.53661 | Null | 6 | Null | five | 
| 4866.4421695257315843 | Null | 7 | Null | five | 
| 4912.8924871001031992 | Null | eight | Null | five | 
| 4940.0480561122244489 | Null | Null | Null | five | 
 So it is not very clear, we will bring the result to the 
bit (3) type :
 SELECT avg(amount), p.city_id, c.state_id, c.country_id, grouping(p.city_id, c.state_id, c.country_id) :: BIT(3) FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY GROUPING SETS(p.city_id, c.state_id, c.country_id, ()); 
Query result| avg | city_id | state_id | country_id | grouping | 
|---|
| 4841.87944 | one | Null | Null | 011 | 
| 5141.313996062992126 | 2 | Null | Null | 011 | 
| 4850.9681893004115226 | 3 | Null | Null | 011 | 
| 4958.2827659574468085 | four | Null | Null | 011 | 
| 4849.1418958333333333 | five | Null | Null | 011 | 
| 5096.8224453280318091 | 6 | Null | Null | 011 | 
| 5208.2182942430703625 | 7 | Null | Null | 011 | 
| 4985.5449561403508772 | eight | Null | Null | 011 | 
| 5038.6109236947791165 | 9 | Null | Null | 011 | 
| 5135.6744234404536862 | ten | Null | Null | 011 | 
| 5219.3821102661596958 | eleven | Null | Null | 011 | 
| 4903.4958541266794626 | 12 | Null | Null | 011 | 
| 5092.9684677419354839 | 13 | Null | Null | 011 | 
| 5006.5867495559502664 | 14 | Null | Null | 011 | 
| 4964.9059877800407332 | 15 | Null | Null | 011 | 
| 4992.1859555555555556 | sixteen | Null | Null | 011 | 
| 4694.4786220472440945 | 17 | Null | Null | 011 | 
| 5047.3065217391304348 | 18 | Null | Null | 011 | 
| 4883.1542885375494071 | nineteen | Null | Null | 011 | 
| 4945.392548596112311 | 20 | Null | Null | 011 | 
| 4993.25485 | Null | Null | Null | 111 | 
| 4990.9535879979828543 | Null | Null | one | 110 | 
| 4994.7674129930394432 | Null | Null | 2 | 110 | 
| 5141.313996062992126 | Null | one | Null | 101 | 
| 4941.1371470732907034 | Null | 2 | Null | 101 | 
| 5208.2182942430703625 | Null | 3 | Null | 101 | 
| 4985.5449561403508772 | Null | four | Null | 101 | 
| 5086.8579314720812183 | Null | five | Null | 101 | 
| 5014.53661 | Null | 6 | Null | 101 | 
| 4866.4421695257315843 | Null | 7 | Null | 101 | 
| 4912.8924871001031992 | Null | eight | Null | 101 | 
| 4940.0480561122244489 | Null | Null | Null | 101 | 
 You can also use common grouping and grouping together in a single query using 
GROUPING SETS :
 SELECT avg(amount), c.country_id, p.payment_type_id, p.city_id, c.state_id FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY c.country_id, p.payment_type_id, GROUPING SETS(p.city_id, c.state_id, ()); 
Query result| avg | country_id | payment_type_id | city_id | state_id | 
|---|
| 5024.1955882352941176 | one | one | one | Null | 
| 4871.1540119760479042 | one | one | 2 | Null | 
| 4891.0804861111111111 | one | one | 3 | Null | 
| 5130.3479896907216495 | one | one | four | Null | 
| 4739.4527586206896552 | one | one | five | Null | 
| 4803.7104 | one | one | 6 | Null | 
| 5028.8194375 | one | one | 7 | Null | 
| 4903.6742 | one | one | eight | Null | 
| 4931.2117088122605364 | one | one | Null | Null | 
| 4407.8555056179775281 | one | 2 | one | Null | 
| 5068.5559638554216867 | one | 2 | 2 | Null | 
| 4812.6204093567251462 | one | 2 | 3 | Null | 
| 4564.1131034482758621 | one | 2 | four | Null | 
| 4963.2932530120481928 | one | 2 | five | Null | 
| 5153.3501219512195122 | one | 2 | 6 | Null | 
| 5446.8668965517241379 | one | 2 | 7 | Null | 
| 5057.8818012422360248 | one | 2 | eight | Null | 
| 4917.934422641509434 | one | 2 | Null | Null | 
| 5146.2380921052631579 | one | 3 | one | Null | 
| 5468.14 | one | 3 | 2 | Null | 
| 4855.5371929824561404 | one | 3 | 3 | Null | 
| 5137.8994387755102041 | one | 3 | four | Null | 
| 4831.1288757396449704 | one | 3 | five | Null | 
| 5353.0667682926829268 | one | 3 | 6 | Null | 
| 5172.241280487804878 | one | 3 | 7 | Null | 
| 4989.92 | one | 3 | eight | Null | 
| 5121.7272005988023952 | one | 3 | Null | Null | 
| 5224.1245625 | 2 | one | 9 | Null | 
| 5137.9207142857142857 | 2 | one | ten | Null | 
| 5173.0209625668449198 | 2 | one | eleven | Null | 
| 4735.6070652173913043 | 2 | one | 12 | Null | 
| 5248.0194285714285714 | 2 | one | 13 | Null | 
| 4929.1857978723404255 | 2 | one | 14 | Null | 
| 5086.2014 102564102564 | 2 | one | 15 | Null | 
| 4716.9701273885350318 | 2 | one | sixteen | Null | 
| 4616.2608383233532934 | 2 | one | 17 | Null | 
| 4756.9175641025641026 | 2 | one | 18 | Null | 
| 4698.7787272727272727 | 2 | one | nineteen | Null | 
| 5033.8821276595744681 | 2 | one | 20 | Null | 
| 4947.559810379241517 | 2 | one | Null | Null | 
| 5195.4805945945945946 | 2 | 2 | 9 | Null | 
| 5213.8818617021276596 | 2 | 2 | ten | Null | 
| 5332.2921935483870968 | 2 | 2 | eleven | Null | 
| 4946.331030303030303 | 2 | 2 | 12 | Null | 
| 5020.5288888888888889 | 2 | 2 | 13 | Null | 
| 5019.8181914893617021 | 2 | 2 | 14 | Null | 
| 4875.5393452380952381 | 2 | 2 | 15 | Null | 
| 5169.0016551724137931 | 2 | 2 | sixteen | Null | 
| 4605.4601807228915663 | 2 | 2 | 17 | Null | 
| 4930.9780838323353293 | 2 | 2 | 18 | Null | 
| 4985.6017441860465116 | 2 | 2 | nineteen | Null | 
| 5137.4943046357615894 | 2 | 2 | 20 | Null | 
| 5035.3225511732401398 | 2 | 2 | Null | Null | 
| 4654.930718954248366 | 2 | 3 | 9 | Null | 
| 5048.5046242774566474 | 2 | 3 | ten | Null | 
| 5171.3846739130434783 | 2 | 3 | eleven | Null | 
| 5042.0059302325581395 | 2 | 3 | 12 | Null | 
| 4997.4288095238095238 | 2 | 3 | 13 | Null | 
| 5071.0994117647058824 | 2 | 3 | 14 | Null | 
| 4941.5018562874251497 | 2 | 3 | 15 | Null | 
| 5110.9062837837837838 | 2 | 3 | sixteen | Null | 
| 4853.5610857142857143 | 2 | 3 | 17 | Null | 
| 5451.8535625 | 2 | 3 | 18 | Null | 
| 4958.8998816568047337 | 2 | 3 | nineteen | Null | 
| 4702.7937426900584795 | 2 | 3 | 20 | Null | 
| 5001.3644005920078934 | 2 | 3 | Null | Null | 
| 4871.1540119760479042 | one | one | Null | one | 
| 4904.9742705167173252 | one | one | Null | 2 | 
| 5028.8194375 | one | one | Null | 3 | 
| 4903.6742 | one | one | Null | four | 
| 5024.1955882352941176 | one | one | Null | Null | 
| 5068.5559638554216867 | one | 2 | Null | one | 
| 4868.3998074074074074 | one | 2 | Null | 2 | 
| 5446.8668965517241379 | one | 2 | Null | 3 | 
| 5057.8818012422360248 | one | 2 | Null | four | 
| 4407.8555056179775281 | one | 2 | Null | Null | 
| 5468.14 | one | 3 | Null | one | 
| 5045.2698285714285714 | one | 3 | Null | 2 | 
| 5172.241280487804878 | one | 3 | Null | 3 | 
| 4989.92 | one | 3 | Null | four | 
| 5146.2380921052631579 | one | 3 | Null | Null | 
| 5012.7593692022263451 | 2 | one | Null | five | 
| 4998.6716863905325444 | 2 | one | Null | 6 | 
| 4684.1941176470588235 | 2 | one | Null | 7 | 
| 4853.1891176470588235 | 2 | one | Null | eight | 
| 5224.1245625 | 2 | one | Null | Null | 
| 5163.1096456692913386 | 2 | 2 | Null | five | 
| 5015.9978440366972477 | 2 | 2 | Null | 6 | 
| 4768.7078978978978979 | 2 | 2 | Null | 7 | 
| 5056.6103405572755418 | 2 | 2 | Null | eight | 
| 5195.4805945945945946 | 2 | 2 | Null | Null | 
| 5089.1325141776937618 | 2 | 3 | Null | five | 
| 5029.1172686567164179 | 2 | 3 | Null | 6 | 
| 5139.3127164179104478 | 2 | 3 | Null | 7 | 
| 4830.0935588235294118 | 2 | 3 | Null | eight | 
| 4654.930718954248366 | 2 | 3 | Null | Null | 
 You can combine the columns inside the 
GROUPING SETS into groups
 SELECT avg(amount), c.country_id, p.payment_type_id, p.city_id, c.state_id FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY GROUPING SETS((p.payment_type_id, c.country_id), ( c.state_id, p.city_id)); 
Query result| avg | country_id | payment_type_id | city_id | state_id | 
|---|
| 4931.2117088122605364 | one | one | Null | Null | 
| 4947.559810379241517 | 2 | one | Null | Null | 
| 4917.934422641509434 | one | 2 | Null | Null | 
| 5035.3225511732401398 | 2 | 2 | Null | Null | 
| 5121.7272005988023952 | one | 3 | Null | Null | 
| 5001.3644005920078934 | 2 | 3 | Null | Null | 
| 5141.313996062992126 | Null | Null | 2 | one | 
| 4850.9681893004115226 | Null | Null | 3 | 2 | 
| 4958.2827659574468085 | Null | Null | four | 2 | 
| 4849.1418958333333333 | Null | Null | five | 2 | 
| 5096.8224453280318091 | Null | Null | 6 | 2 | 
| 5208.2182942430703625 | Null | Null | 7 | 3 | 
| 4985.5449561403508772 | Null | Null | eight | four | 
| 5135.6744234404536862 | Null | Null | ten | five | 
| 5219.3821102661596958 | Null | Null | eleven | five | 
| 4903.4958541266794626 | Null | Null | 12 | five | 
| 5092.9684677419354839 | Null | Null | 13 | 6 | 
| 5006.5867495559502664 | Null | Null | 14 | 6 | 
| 4964.9059877800407332 | Null | Null | 15 | 6 | 
| 4992.1859555555555556 | Null | Null | sixteen | 6 | 
| 4694.4786220472440945 | Null | Null | 17 | 7 | 
| 5047.3065217391304348 | Null | Null | 18 | 7 | 
| 4883.1542885375494071 | Null | Null | nineteen | eight | 
| 4945.392548596112311 | Null | Null | 20 | eight | 
| 4841.87944 | Null | Null | one | Null | 
| 5038.6109236947791165 | Null | Null | 9 | Null | 
 We now turn to 
CUBE . 
CUBE is something like a multiple 
GROUPING SETS .
CUBE returns data for all possible combinations of columns listed inside. That is, for the case of 
CUBE ( c1, c2, c3 ) (where c1, c2, c3 are the column names), the following combinations will be returned:
(c1, null, null) 
(null, c2, null) 
(null, null, c3) 
(c1, c2, null) 
(c1, null, c3) 
(null, c2, c3) 
(c1, c2, c3) 
(null, null, null)Example:
 SELECT sum(amount), p.payment_type_id, c.country_id, p.city_id FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY CUBE(p.payment_type_id, c.country_id, p.city_id); 
Query result| sum | payment_type_id | country_id | city_id | 
|---|
| 854113.25 | one | one | one | 
| 813482.72 | one | one | 2 | 
| 704315.59 | one | one | 3 | 
| 995287.51 | one | one | four | 
| 687220.65 | one | one | five | 
| 840649.32 | one | one | 6 | 
| 804611.11 | one | one | 7 | 
| 735551.13 | one | one | eight | 
| 6435231.28 | one | one | Null | 
| 835859.93 | one | 2 | 9 | 
| 863170.68 | one | 2 | ten | 
| 967354.92 | one | 2 | eleven | 
| 871351.7 | one | 2 | 12 | 
| 918403.4 | one | 2 | 13 | 
| 926686.93 | one | 2 | 14 | 
| 793447.42 | one | 2 | 15 | 
| 740564.31 | one | 2 | sixteen | 
| 770915.56 | one | 2 | 17 | 
| 742079.14 | one | 2 | 18 | 
| 775298.49 | one | 2 | nineteen | 
| 709777.38 | one | 2 | 20 | 
| 9914909.86 | one | 2 | Null | 
| 16350141.14 | one | Null | Null | 
| 784598.28 | 2 | one | one | 
| 841380.29 | 2 | one | 2 | 
| 822958.09 | 2 | one | 3 | 
| 794155.68 | 2 | one | four | 
| 823906.68 | 2 | one | five | 
| 845149.42 | 2 | one | 6 | 
| 789795.7 | 2 | one | 7 | 
| 814318.97 | 2 | one | eight | 
| 6516263.11 | 2 | one | Null | 
| 961163.91 | 2 | 2 | 9 | 
| 980209.79 | 2 | 2 | ten | 
| 826505.29 | 2 | 2 | eleven | 
| 816144.62 | 2 | 2 | 12 | 
| 768140.92 | 2 | 2 | 13 | 
| 943725.82 | 2 | 2 | 14 | 
| 819090.61 | 2 | 2 | 15 | 
| 749505.24 | 2 | 2 | sixteen | 
| 764506.39 | 2 | 2 | 17 | 
| 823473.34 | 2 | 2 | 18 | 
| 857523.5 | 2 | 2 | nineteen | 
| 775761.64 | 2 | 2 | 20 | 
| 10085751.07 | 2 | 2 | Null | 
| 16602014.18 | 2 | Null | Null | 
| 782228.19 | 3 | one | one | 
| 956924.5 | 3 | one | 2 | 
| 830296.86 | 3 | one | 3 | 
| 1007028.29 | 3 | one | four | 
| 816460.78 | 3 | one | five | 
| 877902.95 | 3 | one | 6 | 
| 848247.57 | 3 | one | 7 | 
| 723538.4 | 3 | one | eight | 
| 6842627.54 | 3 | one | Null | 
| 712204.4 | 3 | 2 | 9 | 
| 873391.3 | 3 | 2 | ten | 
| 951534.78 | 3 | 2 | eleven | 
| 867225.02 | 3 | 2 | 12 | 
| 839568.04 | 3 | 2 | 13 | 
| 948295.59 | 3 | 2 | 14 | 
| 825230.81 | 3 | 2 | 15 | 
| 756414.13 | 3 | 2 | sixteen | 
| 849373.19 | 3 | 2 | 17 | 
| 872296.57 | 3 | 2 | 18 | 
| 838054.08 | 3 | 2 | nineteen | 
| 804177.73 | 3 | 2 | 20 | 
| 10137765.64 | 3 | 2 | Null | 
| 16980393.18 | 3 | Null | Null | 
| 49932548.5 | Null | Null | Null | 
| 854113.25 | one | Null | one | 
| 784598.28 | 2 | Null | one | 
| 782228.19 | 3 | Null | one | 
| 2420939.72 | Null | Null | one | 
| 813482.72 | one | Null | 2 | 
| 841380.29 | 2 | Null | 2 | 
| 956924.5 | 3 | Null | 2 | 
| 2611787.51 | Null | Null | 2 | 
| 704315.59 | one | Null | 3 | 
| 822958.09 | 2 | Null | 3 | 
| 830296.86 | 3 | Null | 3 | 
| 2357570.54 | Null | Null | 3 | 
| 995287.51 | one | Null | four | 
| 794155.68 | 2 | Null | four | 
| 1007028.29 | 3 | Null | four | 
| 2796471.48 | Null | Null | four | 
| 687220.65 | one | Null | five | 
| 823906.68 | 2 | Null | five | 
| 816460.78 | 3 | Null | five | 
| 2327588.11 | Null | Null | five | 
| 840649.32 | one | Null | 6 | 
| 845149.42 | 2 | Null | 6 | 
| 877902.95 | 3 | Null | 6 | 
| 2563701.69 | Null | Null | 6 | 
| 804611.11 | one | Null | 7 | 
| 789795.7 | 2 | Null | 7 | 
| 848247.57 | 3 | Null | 7 | 
| 2442654.38 | Null | Null | 7 | 
| 735551.13 | one | Null | eight | 
| 814318.97 | 2 | Null | eight | 
| 723538.4 | 3 | Null | eight | 
| 2273408.5 | Null | Null | eight | 
| 835859.93 | one | Null | 9 | 
| 961163.91 | 2 | Null | 9 | 
| 712204.4 | 3 | Null | 9 | 
| 2509228.24 | Null | Null | 9 | 
| 863170.68 | one | Null | ten | 
| 980209.79 | 2 | Null | ten | 
| 873391.3 | 3 | Null | ten | 
| 2716771.77 | Null | Null | ten | 
| 967354.92 | one | Null | eleven | 
| 826505.29 | 2 | Null | eleven | 
| 951534.78 | 3 | Null | eleven | 
| 2745394.99 | Null | Null | eleven | 
| 871351.7 | one | Null | 12 | 
| 816144.62 | 2 | Null | 12 | 
| 867225.02 | 3 | Null | 12 | 
| 2554721.34 | Null | Null | 12 | 
| 918403.4 | one | Null | 13 | 
| 768140.92 | 2 | Null | 13 | 
| 839568.04 | 3 | Null | 13 | 
| 2526112.36 | Null | Null | 13 | 
| 926686.93 | one | Null | 14 | 
| 943725.82 | 2 | Null | 14 | 
| 948295.59 | 3 | Null | 14 | 
| 2818708.34 | Null | Null | 14 | 
| 793447.42 | one | Null | 15 | 
| 819090.61 | 2 | Null | 15 | 
| 825230.81 | 3 | Null | 15 | 
| 2437768.84 | Null | Null | 15 | 
| 740564.31 | one | Null | sixteen | 
| 749505.24 | 2 | Null | sixteen | 
| 756414.13 | 3 | Null | sixteen | 
| 2246483.68 | Null | Null | sixteen | 
| 770915.56 | one | Null | 17 | 
| 764506.39 | 2 | Null | 17 | 
| 849373.19 | 3 | Null | 17 | 
| 2384795.14 | Null | Null | 17 | 
| 742079.14 | one | Null | 18 | 
| 823473.34 | 2 | Null | 18 | 
| 872296.57 | 3 | Null | 18 | 
| 2437849.05 | Null | Null | 18 | 
| 775298.49 | one | Null | nineteen | 
| 857523.5 | 2 | Null | nineteen | 
| 838054.08 | 3 | Null | nineteen | 
| 2470876.07 | Null | Null | nineteen | 
| 709777.38 | one | Null | 20 | 
| 775761.64 | 2 | Null | 20 | 
| 804177.73 | 3 | Null | 20 | 
| 2289716.75 | Null | Null | 20 | 
| 2420939.72 | Null | one | one | 
| 2611787.51 | Null | one | 2 | 
| 2357570.54 | Null | one | 3 | 
| 2796471.48 | Null | one | four | 
| 2327588.11 | Null | one | five | 
| 2563701.69 | Null | one | 6 | 
| 2442654.38 | Null | one | 7 | 
| 2273408.5 | Null | one | eight | 
| 19794121.93 | Null | one | Null | 
| 2509228.24 | Null | 2 | 9 | 
| 2716771.77 | Null | 2 | ten | 
| 2745394.99 | Null | 2 | eleven | 
| 2554721.34 | Null | 2 | 12 | 
| 2526112.36 | Null | 2 | 13 | 
| 2818708.34 | Null | 2 | 14 | 
| 2437768.84 | Null | 2 | 15 | 
| 2246483.68 | Null | 2 | sixteen | 
| 2384795.14 | Null | 2 | 17 | 
| 2437849.05 | Null | 2 | 18 | 
| 2470876.07 | Null | 2 | nineteen | 
| 2289716.75 | Null | 2 | 20 | 
| 30138426.57 | Null | 2 | Null | 
 As in 
GROUPING SETS, you can do grouping inside:
 SELECT sum(amount), p.payment_type_id, c.country_id, p.city_id FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY CUBE(p.payment_type_id, (c.country_id, p.city_id)); 
Query result| sum | payment_type_id | country_id | city_id | 
|---|
| 854113.25 | one | one | one | 
| 813482.72 | one | one | 2 | 
| 704315.59 | one | one | 3 | 
| 995287.51 | one | one | four | 
| 687220.65 | one | one | five | 
| 840649.32 | one | one | 6 | 
| 804611.11 | one | one | 7 | 
| 735551.13 | one | one | eight | 
| 835859.93 | one | 2 | 9 | 
| 863170.68 | one | 2 | ten | 
| 967354.92 | one | 2 | eleven | 
| 871351.7 | one | 2 | 12 | 
| 918403.4 | one | 2 | 13 | 
| 926686.93 | one | 2 | 14 | 
| 793447.42 | one | 2 | 15 | 
| 740564.31 | one | 2 | sixteen | 
| 770915.56 | one | 2 | 17 | 
| 742079.14 | one | 2 | 18 | 
| 775298.49 | one | 2 | nineteen | 
| 709777.38 | one | 2 | 20 | 
| 16350141.14 | one | Null | Null | 
| 784598.28 | 2 | one | one | 
| 841380.29 | 2 | one | 2 | 
| 822958.09 | 2 | one | 3 | 
| 794155.68 | 2 | one | four | 
| 823906.68 | 2 | one | five | 
| 845149.42 | 2 | one | 6 | 
| 789795.7 | 2 | one | 7 | 
| 814318.97 | 2 | one | eight | 
| 961163.91 | 2 | 2 | 9 | 
| 980209.79 | 2 | 2 | ten | 
| 826505.29 | 2 | 2 | eleven | 
| 816144.62 | 2 | 2 | 12 | 
| 768140.92 | 2 | 2 | 13 | 
| 943725.82 | 2 | 2 | 14 | 
| 819090.61 | 2 | 2 | 15 | 
| 749505.24 | 2 | 2 | sixteen | 
| 764506.39 | 2 | 2 | 17 | 
| 823473.34 | 2 | 2 | 18 | 
| 857523.5 | 2 | 2 | nineteen | 
| 775761.64 | 2 | 2 | 20 | 
| 16602014.18 | 2 | Null | Null | 
| 782228.19 | 3 | one | one | 
| 956924.5 | 3 | one | 2 | 
| 830296.86 | 3 | one | 3 | 
| 1007028.29 | 3 | one | four | 
| 816460.78 | 3 | one | five | 
| 877902.95 | 3 | one | 6 | 
| 848247.57 | 3 | one | 7 | 
| 723538.4 | 3 | one | eight | 
| 712204.4 | 3 | 2 | 9 | 
| 873391.3 | 3 | 2 | ten | 
| 951534.78 | 3 | 2 | eleven | 
| 867225.02 | 3 | 2 | 12 | 
| 839568.04 | 3 | 2 | 13 | 
| 948295.59 | 3 | 2 | 14 | 
| 825230.81 | 3 | 2 | 15 | 
| 756414.13 | 3 | 2 | sixteen | 
| 849373.19 | 3 | 2 | 17 | 
| 872296.57 | 3 | 2 | 18 | 
| 838054.08 | 3 | 2 | nineteen | 
| 804177.73 | 3 | 2 | 20 | 
| 16980393.18 | 3 | Null | Null | 
| 49932548.5 | Null | Null | Null | 
| 2420939.72 | Null | one | one | 
| 2611787.51 | Null | one | 2 | 
| 2357570.54 | Null | one | 3 | 
| 2796471.48 | Null | one | four | 
| 2327588.11 | Null | one | five | 
| 2563701.69 | Null | one | 6 | 
| 2442654.38 | Null | one | 7 | 
| 2273408.5 | Null | one | eight | 
| 2509228.24 | Null | 2 | 9 | 
| 2716771.77 | Null | 2 | ten | 
| 2745394.99 | Null | 2 | eleven | 
| 2554721.34 | Null | 2 | 12 | 
| 2526112.36 | Null | 2 | 13 | 
| 2818708.34 | Null | 2 | 14 | 
| 2437768.84 | Null | 2 | 15 | 
| 2246483.68 | Null | 2 | sixteen | 
| 2384795.14 | Null | 2 | 17 | 
| 2437849.05 | Null | 2 | 18 | 
| 2470876.07 | Null | 2 | nineteen | 
| 2289716.75 | Null | 2 | 20 | 
 ROLLUP is the same as 
CUBE - something like multiple 
GROUPING SETS , with the difference that 
ROLLUP generates combinations, removing columns one by one from the end. Thus, 
ROLLUP ( c1, c2, c3, c4 ) will return the following combinations:
(c1, c2, c3, c4) 
(c1, c2, c3, null) 
(c1, c2, null, null) 
(c1, null, null, null) 
(null, null, null, null)Example:
 SELECT sum(amount), p.payment_type_id, c.country_id, p.city_id FROM payment AS p INNER JOIN city AS c ON p.city_id = c.id GROUP BY ROLLUP(p.payment_type_id, c.country_id, p.city_id); 
Query result| sum | payment_type_id | country_id | city_id | 
|---|
| 854113.25 | one | one | one | 
| 813482.72 | one | one | 2 | 
| 704315.59 | one | one | 3 | 
| 995287.51 | one | one | four | 
| 687220.65 | one | one | five | 
| 840649.32 | one | one | 6 | 
| 804611.11 | one | one | 7 | 
| 735551.13 | one | one | eight | 
| 6435231.28 | one | one | Null | 
| 835859.93 | one | 2 | 9 | 
| 863170.68 | one | 2 | ten | 
| 967354.92 | one | 2 | eleven | 
| 871351.7 | one | 2 | 12 | 
| 918403.4 | one | 2 | 13 | 
| 926686.93 | one | 2 | 14 | 
| 793447.42 | one | 2 | 15 | 
| 740564.31 | one | 2 | sixteen | 
| 770915.56 | one | 2 | 17 | 
| 742079.14 | one | 2 | 18 | 
| 775298.49 | one | 2 | nineteen | 
| 709777.38 | one | 2 | 20 | 
| 9914909.86 | one | 2 | Null | 
| 16350141.14 | one | Null | Null | 
| 784598.28 | 2 | one | one | 
| 841380.29 | 2 | one | 2 | 
| 822958.09 | 2 | one | 3 | 
| 794155.68 | 2 | one | four | 
| 823906.68 | 2 | one | five | 
| 845149.42 | 2 | one | 6 | 
| 789795.7 | 2 | one | 7 | 
| 814318.97 | 2 | one | eight | 
| 6516263.11 | 2 | one | Null | 
| 961163.91 | 2 | 2 | 9 | 
| 980209.79 | 2 | 2 | ten | 
| 826505.29 | 2 | 2 | eleven | 
| 816144.62 | 2 | 2 | 12 | 
| 768140.92 | 2 | 2 | 13 | 
| 943725.82 | 2 | 2 | 14 | 
| 819090.61 | 2 | 2 | 15 | 
| 749505.24 | 2 | 2 | sixteen | 
| 764506.39 | 2 | 2 | 17 | 
| 823473.34 | 2 | 2 | 18 | 
| 857523.5 | 2 | 2 | nineteen | 
| 775761.64 | 2 | 2 | 20 | 
| 10085751.07 | 2 | 2 | Null | 
| 16602014.18 | 2 | Null | Null | 
| 782228.19 | 3 | one | one | 
| 956924.5 | 3 | one | 2 | 
| 830296.86 | 3 | one | 3 | 
| 1007028.29 | 3 | one | four | 
| 816460.78 | 3 | one | five | 
| 877902.95 | 3 | one | 6 | 
| 848247.57 | 3 | one | 7 | 
| 723538.4 | 3 | one | eight | 
| 6842627.54 | 3 | one | Null | 
| 712204.4 | 3 | 2 | 9 | 
| 873391.3 | 3 | 2 | ten | 
| 951534.78 | 3 | 2 | eleven | 
| 867225.02 | 3 | 2 | 12 | 
| 839568.04 | 3 | 2 | 13 | 
| 948295.59 | 3 | 2 | 14 | 
| 825230.81 | 3 | 2 | 15 | 
| 756414.13 | 3 | 2 | sixteen | 
| 849373.19 | 3 | 2 | 17 | 
| 872296.57 | 3 | 2 | 18 | 
| 838054.08 | 3 | 2 | nineteen | 
| 804177.73 | 3 | 2 | 20 | 
| 10137765.64 | 3 | 2 | Null | 
| 16980393.18 | 3 | Null | Null | 
| 49932548.5 | Null | Null | Null | 
 In conclusion, I want to say that, besides the convenience of writing, these queries are potentially (not yet merit), work faster, since to execute a query you need only one table scan instead of several that are performed in the case of 
UNION ALL .
')
Thanks for attention!