2014-02-10 6 views
6

Zur Zeit spielen mit JSON-Felder in Postgres 9.3 zum ersten Mal und ich habe Schwierigkeiten mit der Abfrage von Arrays.Abfrage von Daten innerhalb des JSON-Array-Datenfeldes

Das Feld mit dem Array-Datentyp JSON ist die Konten "genannt und einige Beispieldaten wäre als

folgt
[{name: "foo", account_id: "123"}, {name: "bar", account_id: "321"}] 

Ich möchte die ID des Unternehmens zu finden in der Lage sein, die account_id 123 zum Beispiel besitzt . Die Abfrage, die ich mit zur Zeit Probleme, ist wie folgt:

select id from companies where json_array_elements(accounts)->>'account_id' = '123' 

Dies zu einem Fehler führt:

argument of WHERE must not return a set

+0

ich Ihre Absicht zu erraten ist mehr wie „* wenn ** alle ** die Elemente haben eine' account_id' von '123' dann die entsprechende Firmen ID *" ...?. –

Antwort

11

json_array_elements(...) gibt einen Satz, und zwar das Ergebnis der Anwendung ->> und = zu der Satz. Beachten Sie:

regress=> select json_array_elements('[{"name": "foo", "account_id": "123"}, {"name": "bar", "account_id": "321"}]') ->> 'account_id' = '123'; 
?column? 
---------- 
t 
f 
(2 rows) 

Sie würden erwarten, dass nur in der Lage sein '123' = ANY (...) zu schreiben, aber das ist nicht ohne Array-Eingang unterstützt, leider. Überraschenderweise ist das auch nicht '123' IN (...), etwas, von dem ich denke, dass wir es reparieren müssen.

Also würde ich LATERAL verwenden. Hier ist eine Möglichkeit, die eine Identifizierungsnummer mehrmals zurück, wenn es mehrere Übereinstimmungen hat:

CREATE TABLE company AS SELECT 1 AS id, '[{"name": "foo", "account_id": "123"}, {"name": "bar", "account_id": "321"}]'::json AS accounts; 

SELECT id 
FROM company c, 
LATERAL json_array_elements(c.accounts) acc 
WHERE acc ->> 'account_id' = '123';