2016-06-02 17 views
1

Ich habe eine Osm-Tabelle mit allen Tags in der Hstore-Spalte namens Tags gefunden.Wie Hstore Schlüssel und Werte in separate Spalten in Postgres zerlegen

Ich möchte eine Abfrage schreiben, die eine Tabelle mit allen Spalten der Tabelle und zusätzlichen Spalten für jedes Tag mit jedem Schlüssel als Spaltenname und den Wert darunter zurückgibt. Wie gehe ich da vor?

So wird mein eingegeben werden:

Item_id | tags | 
----------+-------+ 
1614  | apple=2,bees=150| 
1938  | apple=1,bees=50 | 
1983  | apple=1,bees=50 | 
1322  | apple=1,bees=100| 

Ausgabe des Skripts

item_id | apple | bees 
---------+-------+------ 
    1614 | 2 | 150 
    1938 | 1 | 50 
    1983 | 1 | 50 
    1322 | 1 | 100 

unter Berücksichtigung sein wird, die jede Zeile eine variable Menge von Tags haben und ich weiß nicht, was die Zählungen und was sind die Schlüssel an jeder Spalte, so wie gehe ich so zum Beispiel

outp ut wird:

item_id | apple | bees | green | red| 
    ---------+-------+----+--------+----+ 
     1614 | 2 | 150 |345| NULL| 
     1938 | 1 | 50 |NULL| NULL| 
     1983 | 1 | 50 |NULL| NULL| 
     1322 | 1 | 100 |NULL| 346| 

Antwort

0

Hier ist eine Funktion, die einen Tabellennamen und eine Liste von Schlüsseln akzeptiert. Es erstellt dann die neue Tabelle und die neuen Spalten. Es zeigt, wie dynamische Befehle in der Funktion ausgeführt werden. Das SELECT am Ende zeigt, wie Sie Ihre Schlüssel extrahieren. Sie können die Tabelle auffüllen, indem Sie nach dem Erstellen der Spalten die Zeilen Ihrer vorhandenen Tabelle durchlaufen. Es ist mit ziemlicher Sicherheit eine elegantere/effiziente Art und Weise, dies alles zu tun :)

CREATE OR REPLACE FUNCTION explode_hstore(tname text, keys TEXT[]) RETURNS VOID AS $$ DECLARE k TEXT; BEGIN RAISE NOTICE 'Creating table=%', tname; EXECUTE 'CREATE TABLE ' || tname || '()'; FOREACH k IN ARRAY keys LOOP RAISE NOTICE 'Adding column for key=%', k; EXECUTE 'ALTER TABLE ' || tname || ' ADD COLUMN ' || k || ' TEXT'; END LOOP; END; $$ LANGUAGE plpgsql;

die Funktion auszuführen:

SELECT explode_hstore('exploded_hstore', (select array_agg(x.keys) FROM (SELECT skeys("data") AS keys FROM hstoretest GROUP BY keys) x))

+0

Ich muss erwähnen, dass dies wahrscheinlich nicht gut Idee. In den OSM-Daten gibt es über 50.000 eindeutige Tags. Die meisten Apps werden eine Teilmenge vordefinieren und Spalten für sie und Hstore für den Rest verwenden. Diese Untergruppe könnte die gebräuchlichsten Tags oder domänenbezogen (z. B. Straßen) sein. Bedenken Sie auch, dass Postgres ein Limit von 250-16000 Spalten hat (abhängig vom Typ). –