2016-07-11 14 views
1

Dies ist wahrscheinlich ein Standardproblem, und ich habe einige andere Antworten ausgetippt, aber bisher konnte mein aktuelles Problem nicht lösen.Postgres Gruppe nach Spalten und innerhalb der Gruppe Wählen Sie andere Spalten nach max Aggregat

A    B    C 
+----+-------+ +----+------+ +----+------+-------+ 
| id | start | | id | a_id | | id | b_id | name | 
+----+-------+ +----+------+ +----+------+-------+ 
| 1 |  1 | | 1 | 1 | | 1 | 1 | aname | 
| 2 |  2 | | 2 | 1 | | 2 | 2 | aname | 
+----+-------+ | 3 | 2 | | 3 | 3 | aname | 
       +----+------+ | 4 | 3 | bname | 
          +----+------+-------+ 

In Englisch, was ich bewerkstelligen möchte:

  1. Für jede c.name, wählen Sie den neuesten Eintrag auf der Basis der Startzeit in a.Starten

Die SQL ich habe versucht, ist die folgende:

SELECT a.id, a.start, c.id, c.name 
FROM a 
INNER JOIN (
    SELECT id, MAX(start) as start 
    FROM a 
    GROUP BY id 
) a2 ON a.id = a2.id AND a.start = a2.start 
JOIN b 
ON a.id = b.a_id 
JOIN c 
on b.id = c.b_id 
GROUP BY c.name; 

Es schlägt mit Fehlern wie zum Beispiel:

Um nützlich zu sein, brauche ich wirklich die IDs aus der Abfrage, kann aber nicht gruppieren, da sie eindeutig sind. Hier ist ein Beispiel von Ausgang ich für den ersten Fall lieben würde oben:

+------+---------+------+--------+ 
| a.id | a.start | c.id | c.name | 
+------+---------+------+--------+ 
| 2 |  2 | 3 | aname | 
| 2 |  2 | 4 | bname | 
+------+---------+------+--------+ 

Hier ist ein Sqlfiddle

Bearbeiten - entfernt zweiter Fall

+0

'GROUP BY cn ame; 'ist nicht erforderlich. –

+0

Ich würde vorschlagen, dass Sie die zweite Anfrage von dieser Frage entfernen (bevor jemand sie beantwortet), akzeptieren Sie die Antwort mit 'distinct on' und stellen Sie eine andere Frage für den zweiten Teil. Stack Overflow bietet kein zusätzliches Guthaben. –

Antwort

2

Fall 1

select distinct on (c.name) 
    a.id, a.start, c.id, c.name 
from 
    a 
    inner join 
    b on a.id = b.a_id 
    inner join 
    c on b.id = c.b_id 
order by c.name, a.start desc 
; 
id | start | id | name 
----+-------+----+------- 
    2 |  2 | 3 | aname 
    2 |  2 | 4 | bname 

Fall 2

select distinct on (c.name) 
    a.id, a.start, c.id, c.name 
from 
    a 
    inner join 
    b on a.id = b.a_id 
    inner join 
    c on b.id = c.b_id 
where 
    b.a_id in (
     select a_id 
     from b 
     group by a_id 
     having count(*) > 1 
    ) 
order by c.name, a.start desc 
; 
id | start | id | name 
----+-------+----+------- 
    1 |  1 | 1 | aname 
+0

Danke für so eine schnelle Antwort! Wenn ich die distinct auf zusätzliche Spalten in c erweitern muss, nehme ich an, ich füge es einfach an die distinct-Anweisung an, aber auch innerhalb der Reihenfolge nach? Auch ich denke, dass die Leistung davon ziemlich schnell schlecht wird, wenn die Gesamtzeilenzahl des Joins aufgrund mehrerer Sortierungen steigt? –

+0

@DavidE Neben der obligatorischen 'c.name' und der unbeweglichen' a.start' können Sie der 'order by'-Klausel Elemente hinzufügen. Die Auswahlliste ist kostenlos. Überprüfen Sie 'explain analyze' –

Verwandte Themen