Zum Inhalt springen
PostgreSQL - JSONB Keys als Spalten

PostgreSQL - JSONB Keys als Spalten

Beispieldaten

CREATE TABLE geraete (id int, daten jsonb);

INSERT INTO geraete VALUES
  (1, '{"name": "sw01", "ports": 48, "standort": "RZ1"}'),
  (2, '{"name": "sw02", "ports": 24}');
iddaten
1{"name": "sw01", "ports": 48, "standort": "RZ1"}
2{"name": "sw02", "ports": 24}

Einzelne Keys

SELECT id,
       daten->>'name'         AS name,
       (daten->>'ports')::int AS ports
FROM geraete;
idnameports
1sw0148
2sw0224
OperatorErgebnisBeispiel
->Wert als jsonbdaten->'ports'
->>Wert als textdaten->>'ports'
#>>verschachtelter Pfad als textdaten#>>'{netz,vlan}'

Viele Keys

SELECT g.id, j.*
FROM geraete g
CROSS JOIN LATERAL jsonb_to_record(g.daten) AS j(name text, ports int, standort text);
idnameportsstandort
1sw0148RZ1
2sw0224NULL
  • Spaltenname = Key (case-sensitive, Sonderzeichen quoten: "Serial-Nr" text)
  • fehlender Key → NULL
  • Keys ohne Spaltendefinition werden ignoriert
  • nicht castbarer Wert → Fehler, der ganze Query bricht ab

Unbekannte Keys

Spalten müssen beim Schreiben des Queries feststehen, “alle Keys automatisch als Spalten” geht in reinem SQL nicht.

Vorhandene Keys ermitteln

SELECT key, count(*)
FROM geraete, jsonb_object_keys(daten) AS key
GROUP BY key
ORDER BY key;
keycount
name2
ports2
standort1

Key/Value als Zeilen

SELECT g.id, kv.key, kv.value
FROM geraete g
CROSS JOIN LATERAL jsonb_each_text(g.daten) AS kv;
idkeyvalue
1namesw01
1ports48
1standortRZ1
2namesw02
2ports24

Filtern

BeschreibungCommand
Key vorhandenWHERE daten ? 'standort'
Key hat WertWHERE daten @> '{"standort": "RZ1"}'
Vergleich als TextWHERE daten->>'name' = 'sw01'
Index für ? und @>CREATE INDEX ON geraete USING gin (daten);
Zuletzt aktualisiert am