Niestety w składni SQL nie ma przepisu mówiącego „wszystkie kolumny oprócz tej jednej kolumny” . Możesz osiągnąć swój cel, wypisując pozostałą listę kolumn w wyrażeniu typu wiersz :
SELECT a.id, a.name
, json_agg((b.col1, b.col2, b.col3)) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
To skrót od bardziej zrozumiałej formie: . ROW
(b.col1, b.col2, b.col3)
Jednak nazwy kolumn nie są zachowywane w wyrażeniach typu wierszowego. W ten sposób otrzymujesz ogólne nazwy kluczy w obiekcie JSON. Widzę 3 opcje zachowania oryginalnych nazw kolumn:
1. Przesyłaj do zarejestrowanego typu
Rzuć na dobrze znany (zarejestrowany) typ wiersza. Typ jest rejestrowany dla każdej istniejącej tabeli lub widoku lub z wyraźną CREATE TYPE
instrukcją. Możesz użyć tabeli tymczasowej dla rozwiązania ad-hoc (obowiązuje przez czas trwania sesji):
CREATE TEMP TABLE x (col1 int, col2 text, col3 date); -- use adequate data types!
SELECT a.id, a.name
, json_agg((b.col1, b.col2, b.col3)::x) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
2. Użyj podselekcji
Użyj podselekcji, aby zbudować tabelę pochodną i odwołać się do tabeli jako całości . To także przenosi nazwy kolumn. Jest bardziej szczegółowy, ale nie potrzebujesz zarejestrowanego typu:
SELECT a.id, a.name
, json_agg((SELECT x FROM (SELECT b.col1, b.col2, b.col3) AS x)) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
SELECT a.id, a.name
, json_agg(json_build_object('col1', b.col1, 'col2', b.col2, 'col3', b.col3)) AS item
FROM a
JOIN b ON b.item_id = a.id
GROUP BY a.id, a.name;
Związane z:
Podobnie w jsonb
przypadku odpowiednich funkcji jsonb_agg()
i jsonb_build_object()
.
Dla PostgreSQL 9.5 lub nowszy również zobaczyć odpowiedź a_horse w nowym wariancie krótszy składni: Postgres dodał operator minus -
zajsonb
powiedzieć „wszystkie klawisze z wyjątkiem tego jednego klucza” .
Ponieważ Postgres 10 „oprócz kilku kluczy” jest implementowany z tym samym operatorem, który bierze text[]
jako drugi operand - jak komentuje mlt.