structunpivotduckdb

DuckDB - Unnest map that have different keys


EDIT: as a new duckdb user, I misinterpretted the output syntax as a struct it turns out I had created a map

I have a table that contains a map

Product Sales
Widget {Jan=12, Feb=13}
Dongle {Feb=1, Apr=22}

Is there a way to unpivot this so that I get?

Product Month Qty
Widget Jan 12
Widget Feb 13
Dongle Feb 1
Dongle Apr 22

I know the documenation states that structs must have the same keys, but I don't see a clear way to do this with map.


Solution

  • You can get lists of map keys/values and unnest() them.

    Input

    duckdb.sql("""
    create table tbl as (
       select
          unnest(['Widget', 'Dongle']) as Product,
          unnest([
             map(['Jan', 'Feb'], [12, 13]),
             map(['Feb', 'Apr'], [1, 22])
          ]) as Sales
    )   
    """)
    
    ┌─────────┬───────────────────────┐
    │ Product │         Sales         │
    │ varchar │ map(varchar, integer) │
    ├─────────┼───────────────────────┤
    │ Widget  │ {Jan=12, Feb=13}      │
    │ Dongle  │ {Feb=1, Apr=22}       │
    └─────────┴───────────────────────┘
    

    Output

    duckdb.sql("""
    from tbl
    select 
        Product,
        unnest(map_keys(Sales)) as Month,
        unnest(map_values(Sales)) as Qty
    """)
    
    ┌─────────┬─────────┬───────┐
    │ Product │  Month  │  Qty  │
    │ varchar │ varchar │ int32 │
    ├─────────┼─────────┼───────┤
    │ Widget  │ Jan     │    12 │
    │ Widget  │ Feb     │    13 │
    │ Dongle  │ Feb     │     1 │
    │ Dongle  │ Apr     │    22 │
    └─────────┴─────────┴───────┘