Mit einer solchen Abfrage
SELECT a.id, a.name,
COALESCE( json_agg(b.*), '[]'::json ),
COALESCE( json_agg(c.*), '[]'::json ),
FROM a
LEFT JOIN b ON a.id = b.a_id
LEFT JOIN c ON a.id = c.a_id
GROUP BY a.id, a.name;
Bei der Ausführung werden beide cund bmiteinander multipliziert und es werden doppelte Einträge im JSON-Array-Objekt erzeugt.
Ich habe versucht, die Abfrage so zu ändern, dass stattdessen 2 Unterabfragen verwendet werden, erhalte jedoch alle möglichen Fehler und Warnungen, z. B. "Unterabfrage darf nur eine Spalte zurückgeben" usw.
Ich habe es auch versucht LEFT OUTER JOIN, aber ich glaube, ich beherrsche noch nicht, wie das Verknüpfen von Tabellen funktioniert, da es nur für Duplikate gilt bund cimmer noch multipliziert wird und Duplikate enthält.
Bearbeiten : Verwenden von DISTINCTFehlern mit "Konnte keinen Gleichheitsoperator für Typ json identifizieren" für die COALESCEFunktionen.
Wie kann ich diese Abfrage beheben und nur eindeutige Zeilen aggregieren?
Bearbeiten 2
Ich muss angeben, dass beide Tabellen bund ctatsächlich VIEWs sind und beide mindestens eine json_aggSpalte haben, sodass ich sie nicht einfach verwenden kann json_agg(DISTINCT b.*). Das wäre viel zu einfach gewesen.
Bearbeiten 3
Hier ist ein kleiner Ausschnitt, um das Problem zu reproduzieren:
--DROP TABLE IF EXISTS tbl_a CASCADE;
--DROP TABLE IF EXISTS tbl_b CASCADE;
--DROP TABLE IF EXISTS tbl_c CASCADE;
CREATE TABLE tbl_a (
id bigserial NOT NULL,
name character varying(16),
CONSTRAINT "PK_tbl_a" PRIMARY KEY (id)
) WITH ( OIDS=FALSE );
CREATE TABLE tbl_b (
a_id bigint NOT NULL,
foo json NOT NULL DEFAULT '{}'::json,
CONSTRAINT "FK_tbl_b_a" FOREIGN KEY (a_id)
REFERENCES tbl_a (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
) WITH ( OIDS=FALSE );
CREATE TABLE tbl_c (
a_id bigint NOT NULL,
bar json NOT NULL DEFAULT '{}'::json,
CONSTRAINT "FK_tbl_c_a" FOREIGN KEY (a_id)
REFERENCES tbl_a (id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
) WITH ( OIDS=FALSE );
INSERT INTO tbl_a (id,name) VALUES (1, 'Test');
INSERT INTO tbl_b (a_id, foo) VALUES (1, '{"foo":"Hello"}'::json), (1, '{"foo":"World"}'::json);
INSERT INTO tbl_c (a_id, bar) VALUES (1, '{"bar":"abc"}'::json), (1, '{"bar":"def"}'::json);
SELECT tbl_a.id, tbl_a.name,
COALESCE(json_agg(tbl_b.*), '{}'::json),
COALESCE(json_agg(tbl_c.*), '{}'::json)
FROM tbl_a
LEFT JOIN tbl_b ON tbl_a.id = tbl_b.a_id
LEFT JOIN tbl_c ON tbl_a.id = tbl_c.a_id
GROUP BY tbl_a.id, tbl_a.name;
Kehrt zurück
id name coalesce coalesce
-- ------ ------------------------------------ ----------------------
1 "Test" "[{"a_id":1,"foo":{"foo":"World"}}, "[{"a_id":1,"bar":{"bar":"abc"}},
{"a_id":1,"foo":{"foo":"Hello"}}, {"a_id":1,"bar":{"bar":"abc"}},
{"a_id":1,"foo":{"foo":"World"}}, {"a_id":1,"bar":{"bar":"def"}},
{"a_id":1,"foo":{"foo":"Hello"}}]" {"a_id":1,"bar":{"bar":"def"}}]"