Hallo
Folgendes würd ich gerne machen:
Ich hab eine Tabelle mit ca. 13 Millionen Adressdaten.
In dieser Tabelle befinden sich die Spalten ID, Hnr, Strasse, PLZ, Ort und Land.
Nun möchte ich eine zusätzliche Spalte in dieser Tabelle definieren, die folgenden Eintrag hat:
ID || ' ' || HNr || ' ' || Strasse || ' ' || PLZ || ' ' || Ort || ' ' || Land
Da der Datensatz so gross ist sehe ich keine Möglichkeit dies in einem Editor oder Excell zu machen.
Gibt es eine Möglichkeit dies automatisch mit einer Funktion durchzuführen?
z.B. in etwa so:
ALTER TABLE testtabelle ADD COLUMN test text;
INSERT INTO testtabelle (test) VALUES (..Funktion..)
Oder gibt es hierfür eine viel einfachere Möglichkeit?
Freundliche Grüsse
Es gibt keinen Grund die Daten doppelt zu speichern.
Definiere einfach eine VIEW welche die "berechnete" Spalte enthält
Übrigens: wenn eine der Spalten NULL ist, liefert der ganze Ausdruck NULL zurück. Vermutlich willst Du noch ein coalesce(<spalte>, '') für jede (nullable) Spalte verwendenCode:CREATE VIEW v_test AS SELECT id, ID || ' ' || HNr || ' ' || Strasse || ' ' || PLZ || ' ' || Ort || ' ' || Land as komplette_adresse FROM testtabelle
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'
Die Idee ist gut.
Doch so viel ich weiss, ist es nicht möglich einen Index über eine Sicht zu definieren.
Die neue Tabellenspalte brauch ich, damit ich einen GIST Index für meine Abfrage verwenden kann.
Abfrage:
PERFORM set_limit(sim_minimum);
FOR rec IN SELECT Hnr, Strasse, PLZ, Ort, Land, astext(geom), similarity(Input_norm, Strasse || ' ' || Hnr || ' ' || PLZ || ' ' || Ort || ' ' || Land) AS sim FROM testtabelle
WHERE Input_norm % (Strasse || ' ' || HNr || ' ' || PLZ || ' ' || Ort || ' ' || Land)
ORDER BY sim, street DESC
Limit 5
LOOP
RETURN NEXT rec;
END LOOP;
Ach so es geht um's Indizieren, gar nicht um eine berechnte Spalte.
Da müsste es doch reichen einen entsprechenden Index auf der Basis-Tabelle zu definieren.
Ich kenne mich mit GIST Indizes überhaupt nicht aus. Aber einen normalen Index kann man über den Ausdruck definieren.
Einen normalen Index könnte man problemlos so definieren:
Geht sowas mit einem GIST Index nicht?Code:CREATE INDEX idx_sim ON testtabelle ( (Strasse || ' ' || HNr || ' ' || PLZ || ' ' || Ort || ' ' || Land) )
Was genau macht denn der % Operator in Deinem Beispiel?
Wäre die Volltextsuche vielleicht eine Alternative?
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'
Hab das mal ausprobiert
Den GIST Index wollte ich mit folgendem Befehl kreieren:
Leider hat er das nicht verstanden und den Index in dieser Form gemacht:Code:CREATE INDEX idx_kombi ON address USING gist((housenumber || ' ' || street || ' ' || postcode || ' ' || city || ' ' || country) gist_trgm_ops);
Schade eigentlich.Code:CREATE INDEX idx_kombi ON address USING gist (((((((((housenumber::text || ' '::text) || street::text) || ' '::text) || postcode::text) || ' '::text) || city::text) || ' '::text) || country::text) gist_trgm_ops);
Die Bemerkung verstehe ich nicht.
Wird der Index denn verwendet?
Edit: wenn das mit dem Index gar nicht klappt und Du doch eine eigene Spalte machen willst, dann dürfte die schnellste Methode via ADD COLUMN und UPDATE sein:
Du musst dann natürlich über einen Trigger dafür sorgen, dass die Spalte auch immer aktualisiert wird.Code:ALTER TABLE orginal ADD COLUMN volle_adresse text; UPDATE orginal SET volle_addresse = Strasse || ' ' || HNr || ' ' || PLZ || ' ' || Ort || ' ' || Land;
Wie gesagt: Volltextsuche ist vielleicht doch die bessere Alternative.
Geändert von castorp (16.08.2010 um 16:56 Uhr)
A SQL query walks into a bar and sees two tables. He walks up to them and says 'Can I join you?'
Merci für die Antwort
Den GIST Index verwendet er nicht.
Volltextsuche kommt nicht in Frage, weil ich ein Rating brauch.
Dafür verwende ich die pg_trgm similarity Funktion und den % Operator.
So wie ich das sehe, ist die einzige Möglichkeit eine neue Spalte zu definieren. Leider kenn ich mich mit Trigger überhaupt nicht aus.
Hat sonst vielleicht noch jemand eine Idee, wie ich es ohne Trigger machen könnte?
Ist dies überhaupt möglich?
Gruss
Könntest du mir vielleicht ein Beispiel geben, wie der Trigger aussehen müsste.
Würde mir sehr weiterhelfen.
Was soll da drin stehen? Nur die mit || verbundenen Werte anderer Spalten, um dann darüber einen Index zu legen? Reicht nicht auch sowas:
AndreasCode:test=# create table tme (a text, b text, c text); CREATE TABLE test=*# create index idx_tme on tme((a || b || c)); CREATE INDEX test=*# \d tme Table "public.tme" Column | Type | Modifiers --------+------+----------- a | text | b | text | c | text | Indexes: "idx_tme" btree (((a || b) || c))
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
Links: Tobias Bauer - IT- und Funkdienstleistungen - Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen - Funkforum
Lesezeichen