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 c
und b
miteinander 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 b
und c
immer noch multipliziert wird und Duplikate enthält.
Bearbeiten : Verwenden von DISTINCT
Fehlern mit "Konnte keinen Gleichheitsoperator für Typ json identifizieren" für die COALESCE
Funktionen.
Wie kann ich diese Abfrage beheben und nur eindeutige Zeilen aggregieren?
Bearbeiten 2
Ich muss angeben, dass beide Tabellen b
und c
tatsächlich VIEW
s sind und beide mindestens eine json_agg
Spalte 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"}}]"