Estoy tratando de devolver una estructura similar a MAP desde Javascript UDF en bigquery. Para que pueda convertir esa estructura directamente en columnas relacionales sin conocer la columna nombrada antes. En el enfoque a continuación, estoy tratando de encadenar JSON y luego usar la función json_extract_scaler para crear columnas.
CREATE TEMP FUNCTION main(json_str STRING) RETURNS STRING LANGUAGE js AS r""" var row = JSON.parse(json_str); return JSON.stringify(row); """; with temp_table as ( select "ram" name, "ram@gmail.com" email ), Rule_result as (SELECT main(TO_JSON_STRING(STRUCT(t.name, t.email))) result FROM temp_table as t) SELECT json_extract_scalar(result, '$.name') name, json_extract_scalar(result, '$.email') email FROM Rule_result as r;
En este enfoque, estoy devolviendo la estructura, conociendo los nombres de las columnas de antemano.
CREATE TEMP FUNCTION main(json_str STRING) RETURNS STRUCT<name STRING, email STRING> LANGUAGE js AS r""" var row = JSON.parse(json_str); return row; """; with temp_table as ( select "ram" name, "ram@gmail.com" email ), Rule_result as (SELECT main(TO_JSON_STRING(STRUCT(t.name, t.email))) result FROM temp_table as t) SELECT r.result.* FROM Rule_result as r;
Ambos enfoques funcionan bien. Pero no resuelve el problema. Porque necesito estar al tanto de los nombres de las columnas. Bigquery admite el tipo de retorno de estructura, pero eso no se ajusta a mi caso de uso. Como no estoy al tanto de los nombres de las columnas de antemano. ¿Cómo puedo crear dinámicamente columnas a partir de los datos devueltos por el UDF de javascript sin conocer los nombres de las columnas?
{ "name":"ram", "email":"ram@gmail.com" }
De alguna manera necesito convertir este objeto JSON en columnas de tabla como
nombre | |
---|---|
RAM | ram@gmail.com |
Considere a continuación
create temp function extract_keys(input string) returns array<string> language js as """ return Object.keys(JSON.parse(input)); """; create temp function extract_values(input string) returns array<string> language js as """ return Object.values(JSON.parse(input)); """; create temp table tmp as select id, key, value from your_table, unnest(extract_keys(json)) key with offset join unnest(extract_values(json)) value with offset using(offset); execute immediate (select '''select * from tmp pivot (any_value(value) for key in (''' || string_agg(distinct "'" || key || "'") || ''')) ''' from tmp );
si se aplica a datos de muestra como en el ejemplo de su pregunta
la salida es