Interroger des données de variante
Important
Cette fonctionnalité est disponible en préversion publique.
Cet article décrit les opérateurs SQL Databricks que vous pouvez utiliser pour interroger et transformer des données semi-structurées stockées au format JSON VARIANT
. Le type de données VARIANT
est disponible dans Databricks Runtime 15.3 et versions ultérieures.
Databricks recommande d’utiliser VARIANT
sur les chaînes JSON. Pour les utilisateurs qui utilisent actuellement des chaînes JSON qui cherchent à migrer, consultez Comment la variante diffère-t-elle des chaînes JSON ?.
Si vous souhaitez voir des exemples d’interrogation de données semi-structurées stockées avec des chaînes JSON, consultez Chaînes JSON de requête.
Créer une table avec une colonne variant
Exécutez la requête suivante pour créer une table avec des données hautement imbriquées stockées en tant que VARIANT
. Les exemples de cet article font tous référence à cette table.
CREATE TABLE store_data AS
SELECT parse_json(
'{
"store":{
"fruit": [
{"weight":8,"type":"apple"},
{"weight":9,"type":"pear"}
],
"basket":[
[1,2,{"b":"y","a":"x"}],
[3,4],
[5,6]
],
"book":[
{
"author":"Nigel Rees",
"title":"Sayings of the Century",
"category":"reference",
"price":8.95
},
{
"author":"Herman Melville",
"title":"Moby Dick",
"category":"fiction",
"price":8.99,
"isbn":"0-553-21311-3"
},
{
"author":"J. R. R. Tolkien",
"title":"The Lord of the Rings",
"category":"fiction",
"reader":[
{"age":25,"name":"bob"},
{"age":26,"name":"jack"}
],
"price":22.99,
"isbn":"0-395-19395-8"
}
],
"bicycle":{
"price":19.95,
"color":"red"
}
},
"owner":"amy",
"zip code":"94025",
"fb:testid":"1234"
}'
) as raw
Interroger des champs dans une colonne variant
La syntaxe d’interrogation de chaînes JSON et d’autres types de données complexes sur Azure Databricks s’applique aux données VARIANT
, notamment les suivantes :
- Utilisez
:
pour sélectionner des champs de niveau supérieur. - Utilisez
.
ou[<key>]
pour sélectionner des champs imbriqués avec des clés nommées. - Utilisez
[<index>]
pour sélectionner des valeurs dans des tableaux.
Remarque
Si un nom de champ contient un point (.
), vous devez l’échapper entre crochets ([ ]
). Par exemple, la requête suivante sélectionne un champ nommé zip.code
:
SELECT raw:['zip.code'] FROM store_data
Extraire un champ de variante de niveau supérieur
Pour extraire un champ, spécifiez le nom du champ JSON dans votre chemin d’extraction. Les noms de champs respectent toujours la casse.
SELECT raw:owner FROM store_data
+-------+
| owner |
+-------+
| "amy" |
+-------+
-- Use backticks to escape special characters.
SELECT raw:`zip code`, raw:`fb:testid` FROM store_data
+----------+-----------+
| zip code | fb:testid |
+----------+-----------+
| "94025" | "1234" |
+----------+-----------+
Si un chemin d’accès est introuvable, le résultat est NULL
de type VARIANT
.
Extraire des champs imbriqués variants
Vous spécifiez des champs imbriqués à l’aide de la notation par points ou entre crochets. Les noms de champs respectent toujours la casse.
-- Use dot notation
SELECT raw:store.bicycle FROM store_data
+------------------+
| bicycle |
+------------------+
| { |
| "color":"red", |
| "price":19.95 |
| } |
+------------------+
-- Use brackets
SELECT raw:store['bicycle'] FROM store_data
+------------------+
| bicycle |
+------------------+
| { |
| "color":"red", |
| "price":19.95 |
| } |
+------------------+
Si un chemin d’accès est introuvable, le résultat est NULL
de type VARIANT
.
Extraire des valeurs à partir de tableaux de variantes
Vous indexez des éléments dans des tableaux à l’aide de crochets. Les indices sont de base 0.
-- Index elements
SELECT raw:store.fruit[0], raw:store.fruit[1] FROM store_data
+-------------------+------------------+
| fruit | fruit |
+-------------------+------------------+
| { | { |
| "type":"apple", | "type":"pear", |
| "weight":8 | "weight":9 |
| } | } |
+-------------------+------------------+
Si le chemin d’accès est introuvable ou si l’index de tableau est hors limites, le résultat est NULL
.
Aplatir les objets et tableaux de variantes
La fonction de générateur de valeurs de tableau variant_explode
peut être utilisée pour aplatir les tableaux et les objets VARIANT
.
Étant donné que variant_explode
est une fonction de générateur, vous l’utilisez dans le cadre de la clause FROM
plutôt que dans la liste SELECT
, comme dans les exemples suivants :
SELECT key, value
FROM store_data,
LATERAL variant_explode(store_data.raw:store);
+-------+--------------------+
| key| value|
+-------+--------------------+
| basket|[[1,2,{"a":"x","b...|
|bicycle|{"color":"red","p...|
| book|[{"author":"Nigel...|
| fruit|[{"type":"apple",...|
+-------+--------------------+
SELECT pos, value
FROM store_data,
LATERAL variant_explode(store_data.raw:store.basket[0]);
+---+-----------------+
|pos| value|
+---+-----------------+
| 0| 1|
| 1| 2|
| 2|{"a":"x","b":"y"}|
+---+-----------------+
Règles de distribution des types de variantes
Vous pouvez stocker des tableaux et des scalaires en utilisant le type VARIANT
. Lorsque vous essayez de convertir des types de variantes en d’autres types, les règles de distribution normales s’appliquent aux valeurs et champs individuels, avec les règles supplémentaires suivantes.
Remarque
variant_get
et try_variant_get
prenez des arguments de type et suivez ces règles de distribution.
Type de source | Comportement |
---|---|
VOID |
Le résultat est un NULL de type VARIANT . |
ARRAY<elementType> |
elementType doit être un type pouvant être converti en VARIANT . |
Lors de l’inférence de type avec schema_of_variant
ou schema_of_variant_agg
, les fonctions reviennent au type VARIANT
plutôt qu’au type STRING
lorsque des types en conflit sont présents et ne peuvent pas être résolus.
Vous pouvez utiliser ::
ou cast
pour distribuer des valeurs aux types de données pris en charge.
-- price is returned as a double, not a string
SELECT raw:store.bicycle.price::double FROM store_data
+------------------+
| price |
+------------------+
| 19.95 |
+------------------+
-- cast into more complex types
SELECT cast(raw:store.bicycle AS STRUCT<price DOUBLE, color STRING>) bicycle FROM store_data;
-- `::` also supported
SELECT raw:store.bicycle::STRUCT<price DOUBLE, color STRING> bicycle FROM store_data;
+------------------+
| bicycle |
+------------------+
| { |
| "price":19.95, |
| "color":"red" |
| } |
+------------------+
Règles null de variante
Les variantes peuvent contenir deux types de valeurs Null :
- SQL
NULL
: SQLNULL
indique que la valeur est manquante. Il s’agit des mêmesNULL
que lors de la gestion des données structurées. - Variante
NULL
: les variantesNULL
indiquent que la variante contient explicitement une valeurNULL
. Elles ne sont pas identiques auxNULL
de SQL, car la valeurNULL
est stockée dans les données.
Utilisez la fonction is_variant_null
pour déterminer si la valeur de variante est une variante NULL
.
SELECT
is_variant_null(parse_json(NULL)) AS sql_null,
is_variant_null(parse_json('null')) AS variant_null,
is_variant_null(parse_json('{ "field_a": null }'):field_a) AS variant_null_value,
is_variant_null(parse_json('{ "field_a": null }'):missing) AS missing_sql_value_null
+--------+------------+------------------+----------------------+
|sql_null|variant_null|variant_null_value|missing_sql_value_null|
+--------+------------+------------------+----------------------+
| false| true| true| false|
+--------+------------+------------------+----------------------+