Я пытаюсь построить структуру данных в BigQuery с использованием SQL, которая точно отражает структуру данных, которую я получаю при загрузке JSON. Это позволит мне запрашивать представление, используя SQL с точечной нотацией вместо необходимости UNNEST, что я понимаю, но многие из моих клиентов находят это крайне запутанным и не интуитивно понятным.
Если я создаю действительно простой фиктивный набор данных спару строк, а затем вложить, используя шаблон ARRAY_AGG (STRUCT ([список полей])):
WITH
flat_table AS (
SELECT "BigQuery" AS name, 23 AS user_count, "Data Warehouse" AS data_thing, 5 AS ease_of_use, "Awesome" AS description UNION ALL
SELECT "MySQL" AS name, 12 AS user_count, "Database" AS data_thing, 3 AS ease_of_use, "Solid" AS description
)
SELECT
name, user_count,
ARRAY_AGG(STRUCT(data_thing, ease_of_use, description)) AS attributes
FROM flat_table
GROUP BY name, user_count
Затем сохранение и просмотр схемы показывает, что поле attributes
имеет значение Type = RECORD
и Mode = REPEATED
,Имена полей схемы:
name
user_count
attributes
attributes.data_thing
attributes.ease_of_use
attributes.description
Если я посмотрю информацию COLUMN в запросе INFORMATION_SCHEMA.COLUMNS, то увижу, что поля attributes
is_nullable = NO
и data_type = ARRAY<STRUCT<data_thing STRING, ease_of_use INT64, description STRING>>
ЕслиЯ хочу запросить эту структуру, мне нужно использовать шаблон UNNEST, как показано ниже:
SELECT
name,
user_count
FROM
nested_table,
UNNEST(attributes)
WHERE
ease_of_use > 3
Однако, когда я загружаю следующее представление JSON тех же данных в BigQuery с автоматическим определением схемы:
{"attributes":{"description":"Awesome","ease_of_use":5,"data_thing":"Data Warehouse"},"user_count":23,"name":"BigQuery"}
{"attributes":{"description":"Solid","ease_of_use":3,"data_thing":"Database"},"user_count":12,"name":"MySQL"}
Схема выглядит почти идентичной после загрузки, за исключением того, что поле attributes
равно Mode = NULLABLE
(оно все еще Type = RECORD
). INFORMATION_SCHEMA.COLUMNS показывает мне, что поле attributes
теперь is_nullable = YES
и data_type = STRUCT<data_thing STRING, ease_of_use INT64, description STRING>
, то есть теперь может обнуляться, а не в массиве.
Однако самое интересное для меня - это то, что я могу теперь запрашиватьэта таблица использует точечную запись вместо шаблона UNNEST, поэтому приведенный выше запрос выглядит следующим образом:
SELECT
name,
user_count
FROM
nested_table_json
WHERE
attributes.ease_of_use > 3
Что, возможно, легче читать даже в этом тривиальном случае. Однако, как только мы доберемся до более сложных структур данных с несколькими вложенными полями и многоуровневым вложением, шаблон UNNEST становится чрезвычайно трудным для написания, проверки качества и отладки. Шаблон точечной нотации выглядит гораздо более интуитивно понятным и масштабируемым.
Итак, мой вопрос: возможно ли построить структуру данных, эквивалентную загруженному JSON, путем написания запросов в SQL, что позволяет нам создавать запросы стандартного SQLиспользуя точечную запись и не требуя сложных шаблонов UNNEST?