MAP_AGG
Description
The MAP_AGG function is used to form a mapping structure based on key-value pairs from multiple rows of data.
For duplicate keys, MAP_AGG keeps the value encountered first during aggregation and ignores subsequent values for a key that already exists. When partial aggregate states are merged, the value already present in the destination state is also retained.
“Encountered first” refers to processing order, not insertion order. Scanning, parallel execution, and the order in which partial states are merged can affect which value is retained, so the value selected for a duplicate key is not guaranteed to be the same across queries. An outer ORDER BY only sorts result rows; it does not determine which value is retained for a duplicate key.
Syntax
MAP_AGG(<expr1>, <expr2>)
Parameters
| Parameters | Description |
|---|---|
<expr1> | The expression used to specify the key. |
<expr2> | The expression used to specify the corresponding value. |
Return Value
Returns a value of the MAP type.
Example
create table nation(
n_nationkey int,
n_name varchar(32),
n_regionkey int
) properties('replication_num' = '1');
insert into nation values
(0,'ALGERIA',0),(1,'ARGENTINA',1),(2,'BRAZIL',1),(3,'CANADA',1),(4,'EGYPT',4),
(5,'ETHIOPIA',0),(6,'FRANCE',3),(7,'GERMANY',3),(8,'INDIA',2),(9,'INDONESIA',2),
(10,'IRAN',4),(11,'IRAQ',4),(12,'JAPAN',2),(13,'JORDAN',4),(14,'KENYA',0),
(15,'MOROCCO',0),(16,'MOZAMBIQUE',0),(17,'PERU',1),(18,'CHINA',2),(19,'ROMANIA',3),
(20,'SAUDI ARABIA',4),(21,'VIETNAM',2),(22,'RUSSIA',3),(23,'UNITED KINGDOM',3),(24,'UNITED STATES',1);
select `n_nationkey`, `n_name`, `n_regionkey` from `nation`;
+-------------+----------------+-------------+
| n_nationkey | n_name | n_regionkey |
+-------------+----------------+-------------+
| 0 | ALGERIA | 0 |
| 1 | ARGENTINA | 1 |
| 2 | BRAZIL | 1 |
| 3 | CANADA | 1 |
| 4 | EGYPT | 4 |
| 5 | ETHIOPIA | 0 |
| 6 | FRANCE | 3 |
| 7 | GERMANY | 3 |
| 8 | INDIA | 2 |
| 9 | INDONESIA | 2 |
| 10 | IRAN | 4 |
| 11 | IRAQ | 4 |
| 12 | JAPAN | 2 |
| 13 | JORDAN | 4 |
| 14 | KENYA | 0 |
| 15 | MOROCCO | 0 |
| 16 | MOZAMBIQUE | 0 |
| 17 | PERU | 1 |
| 18 | CHINA | 2 |
| 19 | ROMANIA | 3 |
| 20 | SAUDI ARABIA | 4 |
| 21 | VIETNAM | 2 |
| 22 | RUSSIA | 3 |
| 23 | UNITED KINGDOM | 3 |
| 24 | UNITED STATES | 1 |
+-------------+----------------+-------------+
select `n_regionkey`, map_agg(`n_nationkey`, `n_name`) from `nation` group by `n_regionkey`;
+-------------+---------------------------------------------------------------------------+
| n_regionkey | map_agg(`n_nationkey`, `n_name`) |
+-------------+---------------------------------------------------------------------------+
| 1 | {1:"ARGENTINA", 2:"BRAZIL", 3:"CANADA", 17:"PERU", 24:"UNITED STATES"} |
| 0 | {0:"ALGERIA", 5:"ETHIOPIA", 14:"KENYA", 15:"MOROCCO", 16:"MOZAMBIQUE"} |
| 3 | {6:"FRANCE", 7:"GERMANY", 19:"ROMANIA", 22:"RUSSIA", 23:"UNITED KINGDOM"} |
| 4 | {4:"EGYPT", 10:"IRAN", 11:"IRAQ", 13:"JORDAN", 20:"SAUDI ARABIA"} |
| 2 | {8:"INDIA", 9:"INDONESIA", 12:"JAPAN", 18:"CHINA", 21:"VIETNAM"} |
+-------------+---------------------------------------------------------------------------+
select n_regionkey, map_agg(`n_name`, `n_nationkey` % 5) from `nation` group by `n_regionkey`;
+-------------+------------------------------------------------------------------------+
| n_regionkey | map_agg(`n_name`, (`n_nationkey` % 5)) |
+-------------+------------------------------------------------------------------------+
| 2 | {"INDIA":3, "INDONESIA":4, "JAPAN":2, "CHINA":3, "VIETNAM":1} |
| 0 | {"ALGERIA":0, "ETHIOPIA":0, "KENYA":4, "MOROCCO":0, "MOZAMBIQUE":1} |
| 3 | {"FRANCE":1, "GERMANY":2, "ROMANIA":4, "RUSSIA":2, "UNITED KINGDOM":3} |
| 1 | {"ARGENTINA":1, "BRAZIL":2, "CANADA":3, "PERU":2, "UNITED STATES":4} |
| 4 | {"EGYPT":4, "IRAN":0, "IRAQ":1, "JORDAN":3, "SAUDI ARABIA":0} |
+-------------+------------------------------------------------------------------------+
The following query contains a duplicate key, so the result contains only one key-value pair. The result can be {1:"a"} or {1:"b"}, depending on which value is processed first. One possible output is:
SELECT MAP_AGG(k, v) AS result
FROM (
SELECT 1 AS k, 'a' AS v
UNION ALL
SELECT 1 AS k, 'b' AS v
) AS input;
+---------+
| result |
+---------+
| {1:"a"} |
+---------+