2016-04-21 12 views
0

Ich habe eine TabelleUpdate SQL IntArray

table list(
    lst intarray, 
    owner integer); 
table files(
    file_id integer, 
    uid integer 
); 

Für jede owner ich mit allen file_id s platzieren möchten uid in lst corresponing. Ich habe versucht,

update list 
    set lst = lst || file_id 
    FROM files 
    WHERE uid = owner ; 

Die intarray s sind alle auf leere Arrays initialisiert. Es scheint, dass ich bei jeder Ausführung ein einzelnes Element zur Liste hinzufüge. Ich erwarte (und will), dass sie alle auf einmal hinzugefügt werden.

Offensichtlich bin ich verwirrt. Kann jemand helfen zu klären?

Danke.

+0

In Postgres gibt es keinen Datentyp 'Intarray'. –

+0

Es ist eine Erweiterung – LenB

+0

@LenB Ich vermute, es tut etwas mehr als nur 'CREATE DOMAIN intarray AS int []'? Suche nach oben [dieses Modul] (http://www.postgresql.org/docs/current/interactive/intarray.html) aber es gibt keine Erwähnung, dass es einen Typalias hinzufügt, alle Beispiele verwenden nur den Standard 'int [] 'Notation. – IMSoP

Antwort

1

Eine Update-Anweisung (logisch gesehen) zunächst alle Zeilen findet, die Ihren WHERE Zustand übereinstimmen, dann für jede dieser Zeilen, die Aktionen in der SET Klausel gilt. Die Verknüpfungssemantik, die von der FROM-Klausel bereitgestellt wird, ändert dies nicht, daher wird jede Zeile nur einmal aktualisiert.

Was können Sie stattdessen tun ist, um den neuen Wert der Liste in einer einzigen Abfrage zu berechnen, die array_agg Aggregat-Funktion:

SELECT 
    uid, 
    array_agg(file_id) 
FROM 
    files 
GROUP BY 
    uid; 

Da wir nun für jeden Besitzer einer Reihe haben, können wir diese verwenden in unsere UPDATE Aussage; der einfachste Weg, um es in einer Unter Abfrage wäre:

UPDATE list 
    SET lst = subquery.calculated_list 
FROM 
(
    SELECT 
     uid, 
     array_agg(file_id) as calculated_list 
    FROM 
     files 
    GROUP BY 
     uid 
) AS subquery 
WHERE 
    subquery.uid = owner; 

Ich habe a SQLFiddle demo of the above erstellt.

-2

Versuchen Sie folgendes:

UPDATE list 
    SET list.lst = list.lst OR files.file_id 
    FROM list INNER JOIN files ON list.owner = files.uid 
+1

'||' bedeutet nicht das gleiche wie 'OR' - aus irgendeinem Grund ist es der SQL-Standardoperator für" Verketten von Zeichenfolgen ", den Postgres auf ähnliche Aktionen wie" An Array anhängen "erweitert. – IMSoP

+1

Auch der Self-Join wird in der Postgres-Version der 'UPDATE ... FROM'-Syntax explizit nicht benötigt; Wie geschrieben, würde dies effektiv eine "Liste von CROSS JOIN-Listen" ausführen, weil Sie die Tabelle zweimal ohne jegliche Join-Bedingung erwähnt haben. – IMSoP