Récemment mis à niveau pour utiliser PostgreSQL 9.3.1 afin d’exploiter les fonctionnalités JSON. Dans ma table, j'ai une colonne de type JSON qui a une structure comme celle-ci:
{
"id": "123",
"name": "foo",
"emails":[
{
"id": "123",
"address": "somethinghere"
},
{
"id": "456",
"address": "soemthing"
}
]
}
Ce ne sont que des données factices aux fins de la question.
Est-il possible d'interroger un élément spécifique dans le tableau d'e-mails en fonction de l'id?
Assez bien: "email de retour où id = 123)"?
Oui c'est possible:
SELECT *
FROM tbl t, json_array_elements(t.json_col->'emails') AS elem
WHERE elem->>'id' = 123;
tbl
étant votre nom de table, json_col
étant le nom de la colonne JSON.
Plus de détails dans cette réponse:
Plus d'informations sur le CROSS JOIN LATERAL
implicite dans le dernier paragraphe de cette réponse:
Index pour supporter ce type de requête:
Avec une colonne JSONB dans Postgres 9.4+, vous pouvez utiliser l'opérateur contient @>
pour interroger un élément dans un tableau:
SELECT * FROM jsontest WHERE data @> '{ "emails": [{ "id": "123" }] }';
Voir Interroger les éléments de tableau dans le type JSON pour plus de détails.
Voici un exemple de travail:
CREATE TABLE jsontest(data JSONB NOT NULL);
INSERT INTO jsontest VALUES (
'{
"name": "foo",
"id": "123",
"emails":
[
{
"address": "somethinghere",
"id": "123"
},
{
"address": "soemthing",
"id": "456"
}
]
}'
);
SELECT * FROM jsontest WHERE data @> '{ "emails": [{ "id": "123" }] }';
data
----
{"id": "123", "name": "foo", "emails": [{"id": "123", "address": "somethinghere"}, {"id": "456", "address": "soemthing"}]}
(1 rangée)
Entré dans ce post et constaté que vous pouvez interroger directement sur la table comme ceci:
SELECT *
FROM table_name, json_array_elements(json_column) AS data
WHERE data->>'id' = 123;
Omettre cette partie:
json_array_elements(t.json_col->'emails')
Vous pouvez le faire aussi simplement que:
SELECT * FROM table WHERE emails->>'id' = '123';
il semble que vous stockiez l'id sous forme de chaîne. Si c'était un entier, vous pouvez le faire comme ceci
SELECT * from table WHERE cast(emails->>'id' as integer ) = 123 ;
ou vous pouvez obtenir toutes les lignes avec un identifiant> 10
SELECT * from table WHERE cast(emails->>'id' as integer ) > 10 ;