Ergebnis in seperate Spalte eintragen

SELECT (regexp_matches(gfrgebaeude_details_value, '[0-9]{5,}'))[1]::int AS value FROM gfrgebaeude_details WHERE gfrgebaeude_details_value ~ '[0-9]{5,}';    

Damit werden aus einer Textspalte alle Integer-Werte ausgelesen. Diese Werte sollen in eine neue Spalte (Integer) eingetragen werden.


Wie wird aber gewährleistet, dass die gecasten Werte an der richtigen Position (zu den Text-Werten) eingetragen werden?

4000012         4000012         
12.04.2010      NULL
ts1             NULL



test=# select * from t1;
   t
-------
 123
 567
 abc89
(3 Zeilen)

Zeit: 0,231 ms
test=*# alter table t1 add column x int;
ALTER TABLE
Zeit: 0,356 ms
test=*# update t1 set x = regexp_replace(t,'[^0-9]','','g')::int;
UPDATE 3
Zeit: 0,360 ms
test=*# select * from t1;
   t   |  x
-------+-----
 123   | 123
 567   | 567
 abc89 |  89
(3 Zeilen)

Vielleicht so?

Andreas

So klappte die Abfrage.

update myrecords set x  = (regexp_matches(record,'[0-9]{1,}'))[1]::int;

Hier hat er Probleme mit reinem Text

regexp_replace(t,'[^0-9]','','g')::int;

Funktioniert ein regexp_replace auch in einem join?

Ich habe leider keine Rechte, in einer Tabelle eine richtige Spalte (integer) zu erstellen und zu befüllen.

D.h. beim Join muss auf die Integer-Werte aus der Text-Spalte zugegriffen werden…

Ja. Schön ist aber was anderes.

Andreas

Tabelle karl

ha    id
1     1
234   2
ad1   3

Tabelle ha

ha    id
1     1



test=# SELECT * FROM public.ha INNER JOIN public.karl ON (public.ha.nummer = (regexp_matches(public.karl.ha,'[0-9]{8,}'))[1]::int);



FEHLER:  Argument von JOIN/ON darf keine Ergebnismenge zurückgeben
ZEILE 1: ...ELECT * FROM public.ha INNER JOIN public.karl ON (public.ha....

Darf keine Ergebnismenge zurückgeben, was bedeutet das?



test=# select * from t1;
 id
----
  1
  2
  3
(3 rows)

test=*# select * from t2;
  col1   | name
---------+-------
 1       | name1
 2       | name2
 abc3xyz | name3
(3 rows)

test=*# select t1.*, t2.* from t1 left join t2 on (t1.id=regexp_replace(t2.col1,'[^0-9]','','g')::int);
 id |  col1   | name
----+---------+-------
  1 | 1       | name1
  2 | 2       | name2
  3 | abc3xyz | name3
(3 rows)

Andreas

danke, jetzt klappte es.

In den Testdaten geht es:

test=# SELECT * FROM a;
 id_a |  wert_a
------+----------
    1 | 40006302
    8 |      323
(2 Zeilen)

test=# SELECT * FROM aa;
  wert_aa   | id_aa
------------+-------
 40006302   |     1
 11         |     4
 rwe323     |     5
 11.02.2008 |     6
(4 Zeilen)

test=# select a.*,aa.* from a left join aa on (a.wert_a=regexp_replace(aa.wert_aa,'[^0-9]','','g')::int);

 id_a |  wert_a  | wert_aa  | id_aa
------+----------+----------+-------
    1 | 40006302 | 40006302 |     1
    8 |      323 | rwe323   |     5
(2 Zeilen)

Im original kommt immer noch ein Fehler:

geodata=> SELECT gfrgebaeude_details.gfrgebaeude_details_value FROM gfrgebaeude_details WHERE gfrgebaeude_details_key = 'sp1' LIMIT 1;
 gfrgebaeude_details_value
---------------------------
 40006423
(1 Zeile)

geodata=> SELECT kontaktnummer, name FROM gfo_partner LIMIT 1;
 kontaktnummer |                name
---------------+------------------------------------
      40030231 | Eintrag
(1 Zeile)

Nun joine ich die kontaktnummer (Integer) mit gfrgebaeude_details_value (Textfeld)
Im Textfeld sind Datums-, Text- und Integereinträge gemischt.

select gfo_partner.name,  gfrgebaeude_details.gfrgebaeude_details_value from gfo_partner left join  gfrgebaeude_details on (gfo_partner.kontaktnummer =  regexp_replace(gfrgebaeude_details.gfrgebaeude_details_value,'[^0-9]','','g')::int);                                               

ERROR:  invalid input syntax for integer: ""

Liegt der Fehler im regexp?

Nein. Du hast da offensichtlich einen String, der nur aus Leerzeichen besteht.

test=*# copy t1 from stdin;
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>> 4
>> \.
test=*# commit;
COMMIT
test=# select t1.*, t2.* from t1 left join t2 on (t1.id=regexp_replace(public.t2.col1,'[^0-9]','','g')::int);
 id |  col1   | name
----+---------+-------
  1 | 1       | name1
  2 | 2       | name2
  3 | abc3xyz | name3
  4 |         |
(4 rows)

test=*# copy t2 from stdin;
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>>      name4
>> \.
test=*# commit;
COMMIT
test=# select t1.*, t2.* from t1 left join t2 on (t1.id=regexp_replace(public.t2.col1,'[^0-9]','','g')::int);
ERROR:  invalid input syntax for integer: ""

nicht zu sehen ist, daß ich da ein Leerzeichen eingab.

Prinzipiell: man kann sowas machen (JOIN auf das Resultat einer Funktion und wildes rumCASTen), schön ist was anderes.



Andreas

Da sind Werte in der DB, welche aus keinem String bestehen. Also kein NULL, einfach nichts.

Ärgerlich, dass ich damit arbeiten muss.

Edit:
Dazu kommt noch, dass die leeren Strings wahrscheinlich bestehen bleiben müssen.

okay, zum letzten Mal heute.

Ich könnte doch zuerst alle Einträge mit leerem String ausfiltern.

 
SELECT gfrgebaeude_details.gfrgebaeude_details_value FROM gfrgebaeude_details WHERE gfrgebaeude_details.gfrgebaeude_details_value != '' AND gfrgebaeude_details.gfrgebaeude_details_value != '0' AND gfrgebaeude_details.gfrgebaeude_details_value != '-1'

Dann mit der alten Abfrage kombinieren.
kombiniert

SELECT gfo_partner.name, gfrgebaeude_details.gfrgebaeude_details_value from gfo_partner left join gfrgebaeude_details on (gfo_partner.kontaktnummer = regexp_replace(gfrgebaeude_details.gfrgebaeude_details_value,'[^0-9]','','g')::int);"



test=> SELECT gfo_partner.name, gfrgebaeude_details.gfrgebaeude_details_value from gfo_partner left join gfrgebaeude_details on (gfo_partner.kontaktnummer = regexp_replace((SELECT gfrgebaeude_details.gfrgebaeude_details_value FROM gfrgebaeude_details WHERE gfrgebaeude_details.gfrgebaeude_details_value != '' AND gfrgebaeude_details.gfrgebaeude_details_value != '0' AND gfrgebaeude_details.gfrgebaeude_details_value != '-1'),'[^0-9]','','g')::int);

ERROR:  more than one row returned by a subquery used as an expression

Das wäre, wenn es geht zwar nicht schön. Aber es würde reichen.