2017-02-12 7 views
0

Ich habe eine Frage zu lateralen Joins in Postgres.Postgres Lateral Join mehrere Tabellen, um die Ergebnisse zu begrenzen

Mein Anwendungsfall ist, ich möchte ein Dataset zurückgeben, das mehrere Tabellen kombiniert, aber die Anzahl der Publikationen und Rezensionen beschränkt. Die vereinfachte Tabellenschema ist unter

Tabelle Autor

  • ID
  • Name

Tabelle Bewertung

  • ID
  • AUTHOR_ID
  • publication_id
  • CONTENT

Tabelle Veröffentlichung

  • ID
  • Name

Tabelle AuthorPublication

  • AUTHOR_ID
  • publication_id

Also für meine erste Abfrage habe ich dies:

SELECT a.id, a.name json_agg ( json_build_object ( 'id', r.id, 'content', r.content ) ) AS reviews, json_agg ( json_build_object( 'id', p.id, 'name', p.name ) ) AS publications FROM public.author a INNER JOIN public.review r ON r.author_id = a.id INNER JOIN public.author_publication ap ON ap.author_id = a.id INNER JOIN public.publication p ON p.id = ap.publication_id WHERE a.id = '1' GROUP BY a.id

Dies gibt die Daten, die ich brauche, zum Beispiel bekomme ich den Namen des Autors , ID und eine Liste aller ihrer Rezensionen und Publikationen, zu denen sie gehören. Ich möchte die Anzahl der Rezensionen und Veröffentlichungen begrenzen. Zum Beispiel geben Sie 5 Bewertungen und 3 Publikationen zurück.

Ich habe versucht, dies mit einer lateralen Abfrage, aber bin auf ein Problem, wo, wenn ich eine einzige Querabfrage tun es funktioniert wie beabsichtigt.

so wie:

INNER JOIN LATERAL (SELECT r.* FROM public.review r WHERE r.author_id = a.id LIMIT 5) r ON TRUE Diese den Datensatz mit nur 5 Bewertungen zurück - aber wenn ich eine zweite seitliche Abfrage

INNER JOIN LATERAL (SELECT ap.* FROM public.author_publication ap WHERE ap.author_id = a.id LIMIT 5) r ON TRUE

hinzufügen ich jetzt 25 Ergebnisse für beide Bewertungen und Publikationen mit wiederholte/duplizierte Daten.

Also meine Frage ist, dürfen Sie mehrere laterale Joins in einer einzigen PG-Abfrage haben und wenn ja, was ist ein guter Weg, um die Anzahl der Ergebnisse von einem JOIN zu begrenzen?

Danke!

Antwort

0

Sie müssen Ihre Abfrage so etwas wie dies ändern:

SELECT 
    a.id, 
    a.name, 
    (
    SELECT 
     json_agg (r) 
     FROM (
      SELECT 
        json_build_object (
         'id', r.id, 
         'content', r.content 
       ) AS r 
       FROM public.review r 
       WHERE r.author_id = a.id 
       ORDER BY r.id 
       LIMIT 5 
      ) AS a 
) AS reviews, 
    (
    SELECT 
     json_agg (p) 
    FROM (
      SELECT 
       json_build_object(
        'id', p.id, 
        'name', p.name 
       ) AS p 
       FROM public.author_publication ap 
      INNER JOIN public.publication p ON p.id = ap.publication_id 
      WHERE ap.author_id = a.id 
      ORDER BY p.id 
      LIMIT 3 
     ) AS a 
    ) AS publications 
FROM 
    public.author a 
WHERE 
    a.id = '1' 
+0

Wenn ich meine Abfrage aktualisieren, was Sie vorgeschlagen, dass ich die folgende Fehlermeldung erhalten: '' ' Spalte„r.id“muss erscheinen in '' ' [Err] ERROR:: die GROUP BY-Klausel oder in einer Aggregatfunktion ' '' und das Hinzufügen einer GROUP BY gibt mir verwendet werden, mehr als eine Zeile zurück als Ausdruck verwendet, von einer Unterabfrage ' '' Aber wenn ich nur auf 1 limitiere, dann bekomme ich nur das eine Ergebnis. – KukicAdo

+0

Eine andere interessante Sache, die ich herausfinden werde, ist die folgende Abfrage auszuführen: '' 'SELECT json_agg (r.uuid) VON public.review r WHERE r.author_uuid = 'b3113a70-e4bf-4b30-a9ca-9b0530a3115b' LIMIT 1 '' ' Erstellt erstellt ein JSON-Array mit allen übereinstimmenden Feldern. Aber wenn ich die json_agg entferne, bekomme ich nur 1 Zeile mit dem ersten Feld. – KukicAdo

+0

Sorry, es ist etwas unpraktisch, Abfrage ohne DB-Struktur zu schreiben. Wenn Sie die nächste Frage stellen, geben Sie bitte die CREATE TABLE-Anweisung, einige typische Daten und die erwartete Ausgabe an. –

Verwandte Themen