liveBook · Manning

Struct

As explained in DuckDB in Action

A struct is a named-field data structure in which each field has a defined data type.

A struct is a named-field data structure whose fields have defined types. DuckDB uses structs to represent consistent key–value records and to work with complex nested data efficiently. section 1.7.2 section 1.2

Use structs when:

  • Representing one nested record with fields such as an event ID, player, timestamp, and expected-goals value. section 5.3
  • Reading JSON whose properties are inferred as arrays of STRUCT values. section 5.3
  • Normalizing inconsistent inferred types by casting an entire STRUCT to an explicit schema. section 5.3

Flatten nested shot records

JSON files contain home and away shot arrays. Unnest both arrays, combine their records, and cast numeric fields explicitly: CREATE OR REPLACE VIEW shots AS FROM ( FROM 'xg/shots_*.json' SELECT unnest(h) AS row UNION ALL FROM 'xg/shots_*.json' SELECT unnest(a) AS row ) SELECT CAST(row AS STRUCT( id BIGINT, "minute" BIGINT, result VARCHAR, X DOUBLE, Y DOUBLE, xG DOUBLE, player VARCHAR, h_a VARCHAR, player_id BIGINT, situation VARCHAR, season BIGINT, shotType VARCHAR, match_id BIGINT, h_team VARCHAR, a_team VARCHAR, h_goals BIGINT, a_goals BIGINT, date TIMESTAMP, player_assisted VARCHAR, lastAction VARCHAR)) AS row; Then expose the fields as columns with `SELECT row.* FROM shots`. The flattened result can support ordinary grouping and aggregation, such as total expected goals by team. section 5.3 section 5.3 section 5.3

column_name = h
column_type = STRUCT(
  id BIGINT, "minute" BIGINT, result VARCHAR,
  X VARCHAR, Y VARCHAR, xG VARCHAR,
  player VARCHAR, h_a VARCHAR, player_id BIGINT,
  situation VARCHAR, season BIGINT, shotType VARCHAR, match_id BIGINT,
  h_team VARCHAR, a_team VARCHAR, h_goals BIGINT, a_goals BIGINT,
  date TIMESTAMP, player_assisted VARCHAR, lastAction VARCHAR)[]
       null = YES
        key =
    default =
      extra =

column_name = a
column_type = STRUCT(
  id BIGINT, "minute" BIGINT, result VARCHAR,
  X VARCHAR, Y VARCHAR, xG VARCHAR,
  player VARCHAR, h_a VARCHAR, player_id BIGINT,
  situation VARCHAR, season BIGINT, shotType VARCHAR, match_id BIGINT,
  h_team VARCHAR, a_team VARCHAR, h_goals BIGINT, a_goals BIGINT,
  date TIMESTAMP, player_assisted VARCHAR, lastAction VARCHAR)[]
       null = YES
        key =
    default =
      extra =

Inspect the inferred STRUCT schema before unnesting or casting nested JSON records. section 5.3

How DuckDB in Action covers it

How deep it goes
Explains definitions, inferred schemas, unnesting, whole-STRUCT casts, field expansion, and aggregation, without detailing internal storage.
Examples
Demonstrates Premier League shot JSON, inferred STRUCT arrays, explicit casts, flattened views, and expected-goals aggregation.
What it assumes
Assumes basic SQL and JSON familiarity while introducing structured data types and nested-record handling.
What you can do after
Apply structs in DuckDB SQL to inspect, normalize, flatten, and aggregate nested JSON records.
How it connects
Connects structs with JSON, lists, maps, enums, unnesting, type casting, and nested-data processing.

Also explained in

Compare how 14 books explain struct →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of DuckDB in Action. The section links point to the parts of the book it draws on.