2016-07-02 4 views
1

Ich habe occasion und relation Tabellen. relation.occasions ist ein JSON-Feld, das ein Array von Gelegenheitsschlüsseln enthält. Ich möchte occasion Datensätze nach Beziehung erhalten, wobei occasion.key in relation.occasions. Es sei angenommen, dass dies mein DB Daten:Verwendung von PostgreSQL json_array_elements WHERE <value> IN-Klausel

Gelegenheit

 key  |  name  | 
------------------------------------- 
    BIRTHDAY  | Birthday | 
    ANNIVERSARY | Anniversary | 

Beziehung

key   | occasions       | 
------------------------------------------------------ 
    FATHER  | [ "BIRTHDAY", "ANNIVERSARY" ] | 
    FRIEND  | [ "BIRTHDAY" ]     | 

Hier ist die Abfrage, die ich zu verwenden, ich versuche:

SELECT * FROM occasion o WHERE o.key IN 
(SELECT json_array_elements(r.occasions)::text from relation r WHERE r.key = 'FATHER') 

Das Ergebnis ist 0 Zeilen statt erwartet 2. Kann mir jemand einen Hinweis geben, was mache ich falsch? Wie kann ich sonst das gewünschte Ergebnis erzielen?

Antwort

2

Die Funktion json_array_elements() gibt einen Satz zurück, kein Array, Sie sollten ihn also als Zeilenquelle verwenden, nicht in der Auswahlliste.

Die richtige Abfrage wäre:

SELECT o.* 
FROM occasion o 
JOIN (
    SELECT DISTINCT j.value 
    FROM relation 
    JOIN LATERAL json_array_elements_text(occasions) j(value) ON true 
    WHERE key = 'FATHER') sub ON o.key = sub.value; 

Sie können es auch ohne die Unterabfrage abflachen, aber ich finde diese Version besser lesbar zu sein (die Abfrage Planer ohnehin die Abflachung tun wird).

+0

'wählen o. * Aus Gelegenheit o join relation r on (o.key = any (wählen Sie json_array_elements_text (r.occasions)) und r.key = 'VATER');' - einfacher ein bisschen, aber vorausgesetzt, dass te Schlüssel ist einzigartig. – Abelisto

+0

@Abelisto Die Verwendung einer SRF in einer Auswahlliste sollte vermieden werden: [Sie werden wie eine Tabelle, eine Sicht oder eine Unterabfrage in der FROM-Klausel einer Abfrage verwendet.] (Https://www.postgresql.org/docs/9.5/ static/queries-table-expressions.html # QUERIES-TABLEFUNCTIONS) – Patrick

+0

Ihr Link bezieht sich genau auf die FROM-Klausel, nicht auf die SRF-Verwendung. [Set Returning Functions] (https://www.postgresql.org/docs/9.5/static/functions-srf.html), Beispiel aus der offiziellen Dokumentation: 'SELECT generate_series (1.1, 4, 1.3);' – Abelisto

Verwandte Themen