2014-01-28 7 views
5

Ich migriere etwas SQL von PostgreSQL 9.2 zu Vertica 7.0, und ich könnte etwas Hilfe verwenden, die coole array_agg Eigenschaft von Postgres durch etwas ersetzt, das Vertica (und möglicherweise andere RDBMS) unterstützt, wie Partitionen und Fensterfunktionen. Ich bin neu in diesen Funktionen, und ich würde Ihre Ideen wirklich schätzen.Wie bekomme ich den ersten (oder einen einzelnen) Wert in GROUP BY ohne ARRAY_AGG?

Das (Arbeits-) Abfrage mit array_agg (sql fiddle demo):

SELECT B.id, (array_agg(A.X))[1] 
FROM B, AB, A 
WHERE B.id = AB.B_id AND A.id = AB.A_id AND A.X IS NOT NULL 
GROUP BY B.id; 

Wenn ich versuche, von selbst zu naiv wählen AX ohne die Aggregation (dh die RDBMS holen zu lassen - tatsächlich funktioniert mit MySQL und SQLite) beschwert sich postgres. Ausführen der gleichen Abfrage aber mit "AX" statt "(array_agg (AX)) 1":

ERROR: column "a.x" must appear in the GROUP BY clause or be used in an aggregate function 
LINE 1: SELECT B.id, A.X 

ich eine Fensterfunktion zu versuchen, dachte, zum Beispiel so etwas wie aus this question:

SELECT email, FIRST_VALUE(email) OVER (PARTITION BY email) 
FROM questions 
GROUP BY email; 

aber ich habe den gleichen Fehler:

SELECT B.id, FIRST_VALUE(A.X) OVER (PARTITION BY A.id) 
FROM B, AB, A 
WHERE B.id = AB.B_id AND A.id = AB.A_id AND A.X IS NOT NULL 
GROUP BY B.id; 

ERROR: column "a.x" must appear in the GROUP BY clause or be used in an aggregate function 
LINE 1: SELECT B.id AS id, FIRST_VALUE(A.X) OVER (PARTITION BY A.id)... 

Bitte beachte, dass wir über das erhalten der erste Wert so sehr sie sich nicht, wir müssen nur jede (idealerweise deterministisch) Einzelwert.

Vielen Dank im Voraus.

+1

Ich bin etwas ratlos, was Sie mit '(array_agg (A.X)) [1]' erreichen wollen. Ohne eine Order-by-Klausel erhalten Sie damit den ersten einer zufällig sortierten Liste von A.X. Die Tatsache, dass Sie das Ergebnis erhalten, wird erwartet, ist reines Glück aufgrund der Tatsache, dass Ihre Statistiken Postgres einen Plan vorziehen, der passt ... –

+3

Ich könnte mich irren, aber warum benutzen Sie nicht einfach SELECT B id, min (AX) von ... Gruppe von b.id'? Ich sehe nicht, warum 'array_agg()' überhaupt notwendig wäre. –

Antwort

1

@ a_horse_with_no_name Kommentar, zusammen mit dem von Denis, war was wir brauchten, um unseren Ansatz zu überdenken. Wir sind zu MIN() gewechselt. Vielen Dank!