0

Ich versuche, durch Unterabfrage über ein Aggregat unten zu gruppieren (ich vereinfachte die Abfrage auf seine einfachste Form, eine group by n Abfrage).GROUP BY benutzerdefinierte Aggregat

Aber anstatt einen max verwenden, muß ich jetzt die folgende Heuristik:

bar reicht von 0-2. Ich möchte 2.0.1 in dieser Reihenfolge wählen. Aber ich möchte dann original auf den Original Wert von bar beitreten.

Kann ich eine benutzerdefinierte Aggregatfunktion schreiben, um die richtige Eigenschaft zurückzugeben? Ich bin ein bisschen verloren, wie die beiden zusammenkommen würden.

SELECT 
    FOO.bar2 
FROM 
    FOO 
INNER JOIN(
    SELECT 
     FOO.id, 
     custom_aggrgate(bar) 
    FROM 
     FOO      
    GROUP BY 
     FOO.id    
    ) b ON FOO.bar = inverse_of_custom_aggrgate(bar) -- get org. value of bar to join by 
+1

Können Sie ein Beispiel für Eingabewerte und die von Ihnen gesuchte Ausgabe angeben? – Alex

Antwort

1

Simplest Lösung wäre mit DISTINCT ON und ein CASE Ausdruck in ORDER BY:

Ich nehme an, das ist das, was Sie tatsächlich wollen:

SELECT DISTINCT ON (id) bar2 
FROM foo 
ORDER BY id, CASE bar WHEN 2 THEN -1 ELSE bar END; 

Keine Notwendigkeit für benutzerdefinierte Aggregatfunktion.
Keine weitere Verbindung erforderlich.
Keine Funktion erforderlich, um das Ergebnis der benutzerdefinierten Aggregatfunktion zu invertieren.

Über DISTINCT ON:


Die Abfrage in der Frage ist syntaktisch ungültig und wahrscheinlich nicht das, was Sie wollen. Mit der Syntax behoben, könnte es wie folgt aussehen:

SELECT FOO.bar2 
FROM FOO 
INNER JOIN (
    SELECT FOO.id, custom_aggrgate(bar) AS bar 
    FROM FOO      
    GROUP BY FOO.id    
    ) b ON FOO.bar = inverse_of_custom_aggrgate(b.bar);

Aber das ist wahrscheinlich immer noch Unsinn. Wenn bar nicht eindeutig definiert ist (was in Ihrem Szenario nicht wahrscheinlich erscheint), erhalten Sie viele doppelte Zeilen. Ein Äquivalent für diese zweifelhafte Abfrage wäre:

SELECT f.bar2 
FROM foo f 
JOIN (
    SELECT DISTINCT ON (id) bar 
    FROM foo 
    ORDER BY id, CASE bar WHEN 2 THEN -1 ELSE bar END 
    ) b USING (bar); 

Ich erwarte nicht, dass das, was Sie brauchen.