Tabellenfelder per SQL bearbeiten

Hallo,

muss mich jetzt mehr mit Postgres beschäftigen und komme daher auf folgendes Problem:

In einer Tabelle (Befund) befinden sich u.a. 4 Spalten mit den Bezeichnungen laenge_von, laenge-bis, breite_von und breite_bis.

Die Daten wurden von einer ACCESS-Datenbank übernommen; leider sind die Tabellenfelder alphanumerisch und so ist in den von_Tabellenfeldern meistens der komplette von-bis-Wert in der Form xxx - xxx bzw. xxx-xxx enthalten; die bis_Spalte ist dagegen leer.

Gibt es unter POSTGRES die Möglichkeit, das Von-Feld aufzusplitten und die Werte richtig in die zugehörigen Felder einzutragen oder muss man das mühselig per Hand erledigen?

Habe das Forum schon durchsucht, aber nichts darüber gefunden.

Danke für Eure Antworten.

Freundliche Grüße aus Rotenburg

Bernd



test=*# create table demo (von_bis text, von int, bis int);
CREATE TABLE
Zeit: 63,350 ms
test=*# insert into demo values ('1-5',null,null);
INSERT 0 1
Zeit: 0,324 ms
test=*# update demo set von = regexp_replace(von_bis,'-.*$','')::int, bis=regexp_replace(von_bis,'^.*-','')::int;
UPDATE 1
Zeit: 30,138 ms
test=*# select * from demo;
 von_bis | von | bis
---------+-----+-----
 1-5     |   1 |   5
(1 Zeile)

Andreas

Hallo,

danke für die schnelle Hilfe.

Es existieren ca. 14000 Befunde; beim Durchsehen stelle ich fest, dass das Längenfeld individuell vom Anwender gefüllt wurde.

  1. Das Feld kann leer sein
  2. es kann nur eine Zahl drin stehen
  3. beides ist möglich: 30 - 40 oder 30-40

Alles andere habe ich manuell bereinigt; die neuen Tabellenfelder (lang_von und lang_bis) sollen jetzt numeric sein, da Kommazahlen vorkommen könnten.

So sieht die Abfrage bei mir momentan aus:

Alter table befund add column lang_von numeric;
Alter table befund add column lang_bis numeric;

update befund set lang_von = regexp_replace(laenge,’-.$’,’’)::numeric, lang_bis=regexp_replace(laenge,’^.-’,’’)::numeric;

Leider kommt folgende Fehlermeldung:

FEHLER: ungültige Eingabesyntax für Typ numeric: » «
SQL Status:22P02

Ich glaube, es ist noch ein langer Weg, bis ich Postgres beherrsche…

Gruß Bernd

Das ist nicht PostgreSQL-spezifisch, sondern hat was mit Datentypen und Datenkonsistenz zu tun. Wenn Spielzeuge wie M$-Access jeden Datenmüll annehmen, so ist das deren Sache. Welche Probleme mit dem Umgang später auftreten, erlebst Du gerade.

Zu Deinem Problem:

offensichtlich mag er kein Leerzeichen für einen numerischen Wert annehmen - es ist ja auch kein numerischer Wert. Also eliminiere die Leerzeichen aus dem String. Wenn der String dann leer ist, dann kannst Du den nicht zu numeric casten. Beispiel:

Die Tabelle enthält in der Spalte s Leerzeichen und einmal auch eine 1 mit Leerzeichen. Damit man dies sieht, zeige ich in der zweiten Spalte extra ein ‘x’ vorn/hinten mit an. In der dritten Spalte caste ich nach numeric, sofern möglich.

test=*# select s, 'x'||s||'x', case when length(trim(both ' ' from s)) > 0 then trim(both ' ' from s)::numeric else null end from n;
  s   | ?column? | case
------+----------+------
      | x x      |
      | x   x    |
   1  | x  1 x   |    1
(3 Zeilen)

Bei Problemen wie bei Dir ist es ratsam, die Daten zuerst einmal in eine Import-Tabelle zu holen, deren Spalten vom Typ TEXT sind. Dann bastelt man sich halt ein passendes SQL-Select, und wenn das stimmt und alles klappt, füllt man die eigentliche Zieltabelle damit.

Andreas

Hallo,

stehe vor einem Problem, welches ich mir mit Logik nicht erklären kann:

  1. Ich richte mir im Table befund eine temporäre Spalte ein
  2. In leere Felder soll eine 0 gebracht werden.

Alter table befund add column zwi_tab text;
update befund set zwi_tab = (case when (lang_bis = NULL) then ‘0’ end);

Nach dieser Anweisung ist die Spalte zwi_tab leer.

Ein Select-Befehl auf den Table Befund liefert keine Null-Zeilen der Spalte lang_bis, obwohl die Zeilen rein optisch leer sind.

Der Befehl:
select char_length(lang_bis) from befund

bringt als Ergebnis

  1. ein Leerfeld, obwohl das Tabellenfeld mit einer ‘80’ bestückt ist
  2. den Wert 0, obwohl das Tabellenfeld mit einer ‘30’ bestückt ist

Bei einem anderen Wert ‘324’ wird wiederum der korrekte Zählwert 3 ausgegeben.

Habe mich an demm Problem festgebissen; handelt es sich um einen Bug des neuesten POSTGRESQL/PGADMIN-Gespanns?

Hat Jemand eine Idee?
Danke für Eure Hilfe und Geduld mit einem Anfänger.

Gruß Bernd

aus der doku
If the ELSE clause is omitted and no condition matches, the result is null.

dir fehlt das ELSE im case?

oder verwende doch einfach zwi_tab = CoalEsce(zwi_tab, ‘0’)

ausserdem weiss ich nicht wie du danach auf die null-felder selektierst … ich bin mir nicht sicher aber feld = NULL wird wohl false sein, auch wenn das feld NULL ist … weil NULL = NULL false ist … du solltest mit feld IS NULL prüfen … dann wirst du die NULLs auch sehen

den gleichen “fehler” machst du schon oben im CASE

http://www.postgresql.org/docs/8.1/static/functions-comparison.html

Do not write expression = NULL because NULL is not “equal to” NULL. (The null value represents an unknown value, and it is not known whether two unknown values are equal.) This behavior conforms to the SQL standard.