Flurstück Zähler/Nenner aufsplitten

Steve6

Aktiver Benutzer
Beiträge
26
Hallo Forum,

ich vermute mal, dass ich hier richtig bin :) Seit 2 Tagen google ich mich schon durch die Welt, finde aber die richtige Idee nicht. Oder ich übersehe sie.

Ich habe eine Tabelle:

|Gemarkung | Flur | Flurstueck |
-----------------------------------------
| 1234 | 001 | 62/5 |
| 1234 | 001 | 103/60 |
| 1235 | 023 | 6 |
|1235 | 023 | 1/104 |

Wie schaffe ich es nun, die Spalte Flurstücke nach Zähler und Nenner zu trennen:

|Gemarkung | Flur | Zähler | Nenner |
-----------------------------------------
| 1234 | 001 | 062 | 00005 |
| 1234 | 001 | 103 | 00060 |
| 1235 | 023 | 006 | |
|1235 | 023 | 001 | 00104 |

Dafür reicht mein Oracle SQL leider nicht aus. Wir haben Oracle 11g

Gruß Steve
 
Werbung:

akretschmer

Datenbank-Guru
Beiträge
9.028
Hallo Forum,

ich vermute mal, dass ich hier richtig bin :) Seit 2 Tagen google ich mich schon durch die Welt, finde aber die richtige Idee nicht. Oder ich übersehe sie.

Ich habe eine Tabelle:



Dafür reicht mein Oracle SQL leider nicht aus. Wir haben Oracle 11g

Gruß Steve

Code:
test=*# select to_char(split_part('62/5','/',1)::int,'0999') as zaehler, to_char(split_part('62/5','/',2)::int,'0999') as nenner;
 zaehler | nenner
---------+--------
  0062   |  0005
(1 row)

Sollte ähnlich in Oraggle gehen, ich habe PostgreSQL. Für den Wert setzt halt die Spalte ein.
 

ukulele

Datenbank-Guru
Beiträge
4.394
Wenn es immer sauber durch / getrennt ist geht es auch mit len, left, right und charindex was es zwar in Oracle auch nicht gibt aber natürlich equivalent vorhanden ist. http://nishantrana.wordpress.com/2007/10/03/using-left-and-charindex-in-oracle/ Ganz am Ende findet sich exakt dein Problem beim zerlegen der Zeichenkette.

akretschner hat dann noch in INT konvertiert was aber in der Syntax glaube ich nur in PG geht. Ich bin mir auch nicht sicher ob nicht vieleicht Buchstaben in Flurstücken vorkommen können.
 

Steve6

Aktiver Benutzer
Beiträge
26
Hallo und Danke für die schnellen Tipps und Anregungen.

ich es jetzt so versucht (FELD6 enthält die Flurstücksnummer):

Code:
select FELD6 ,TO_CHAR(substr(FELD6,1,instr(FELD6,'/')-1),'00000') as teil1, substr(FELD6,instr(FELD6,'/')+1) as teil2 FROM TABELLE

So gibt er mir eine Trennung aus. Leider schiebt er mir die Flurstücke ohne /, also die die nur einen Nenner haben, in den Zählerbreich. Was nicht funktionierte war:

Code:
select FELD6 ,TO_CHAR(substr(FELD6,1,instr(FELD6,'/')-1),'00000') as teil1, TO_CHAR(substr(FELD6,instr(FELD6,'/')+1),'0000') as teil2 FROM TABELLE

Der gleiche Code nur mit einen weiteren TO_CHAR hinten. Dann kommt die Meldung:

SQL execution error, ORA-01722: Ungültige Zahl
ORA-02063: vorherige line von TABELLE

Danke und Gruß Steve
 

ukulele

Datenbank-Guru
Beiträge
4.394
Ich hätte es jetzt so gemacht:
Code:
SELECT    Gemarkung,
        Flur,
        substr(Flurstueck,1,instr(Flurstueck,'/')-1) AS Zaehler,
        substr(Flurstueck,(len(Flurstueck)-instr(Flurstueck,'/'))*-1) AS Nenner
FROM    tabelle
Eigentlich müsste to_char() nicht nötig sein, es handelt sich ja bereits um char. Wenn da noch mit Nullen aufgefüllt werden soll würde ich das in einer CASE Schleife unterbringen, finde ich handlicher und sollte in Oracle genauso gehen.
Code:
SELECT    Gemarkung,
        Flur,
        (    CASE
            WHEN    len(substr(Flurstueck,1,instr(Flurstueck,'/')-1)) = 1
            THEN    '00' + substr(Flurstueck,1,instr(Flurstueck,'/')-1)
            WHEN    len(substr(Flurstueck,1,instr(Flurstueck,'/')-1)) = 2
            THEN    '0' + substr(Flurstueck,1,instr(Flurstueck,'/')-1)
            ELSE    substr(Flurstueck,1,instr(Flurstueck,'/')-1)
            END ) AS Zaehler,
        (    CASE
            WHEN    len(substr(Flurstueck,(len(Flurstueck)-instr(Flurstueck,'/'))*-1)) = 1
            THEN    '0000' + substr(Flurstueck,(len(Flurstueck)-instr(Flurstueck,'/'))*-1)
            WHEN    len(substr(Flurstueck,(len(Flurstueck)-instr(Flurstueck,'/'))*-1)) = 2
            THEN    '000' + substr(Flurstueck,(len(Flurstueck)-instr(Flurstueck,'/'))*-1)
            WHEN    len(substr(Flurstueck,(len(Flurstueck)-instr(Flurstueck,'/'))*-1)) = 3
            THEN    '00' + substr(Flurstueck,(len(Flurstueck)-instr(Flurstueck,'/'))*-1)
            WHEN    len(substr(Flurstueck,(len(Flurstueck)-instr(Flurstueck,'/'))*-1)) = 4
            THEN    '0' + substr(Flurstueck,(len(Flurstueck)-instr(Flurstueck,'/'))*-1)
            ELSE    substr(Flurstueck,(len(Flurstueck)-instr(Flurstueck,'/'))*-1)
            END ) AS Nenner
FROM    tabelle
 

akretschmer

Datenbank-Guru
Beiträge
9.028
Eigentlich müsste to_char() nicht nötig sein, es handelt sich ja bereits um char. Wenn da noch mit Nullen aufgefüllt werden soll würde ich das in einer CASE Schleife unterbringen, finde ich handlicher und sollte in Oracle genauso gehen.

Ähm, nun ja. Ich hatte es nach INT gecastet, um dann es einfacher formatieren zu können. Diese substring-Orgie halte ich jetzt nicht wirklich handlich ...
 

Steve6

Aktiver Benutzer
Beiträge
26
Hallo Ukulele,

hier stört es sich an dem len, wenn ich deine Selectanweisung umsetze.

SQL execution error, Der Spaltenname 'LEN' fehlt bzw. ist ungültig.

Ist die Rückmeldung.
 

ukulele

Datenbank-Guru
Beiträge
4.394
Ähm, nun ja. Ich hatte es nach INT gecastet, um dann es einfacher formatieren zu können. Diese substring-Orgie halte ich jetzt nicht wirklich handlich ...
Ja aber deine Konvertierung in INT mit Format und zurück in CHAR habe ich in der Notation bisher nur bei PG gesehen, ich weis nicht ob das bei Oracle auch geht. Ich bezog mich dann auf den Post von Steve6 der to_char bei sich mehrfach eingesetzt hat nur warum weis ich nicht.

Code:
substr(Flurstueck,1,instr(Flurstueck,'/')-1) AS Zaehler
substr(Flurstueck,(len(Flurstueck)-instr(Flurstueck,'/'))*-1) AS Nenner
Die zwei substr() Anweisungen sind jetzt nicht wirklich eine Orgie. Ohne split_part() wüsste ich auch keinen kürzeren Weg ausser vieleicht mit reverse().

hier stört es sich an dem len, wenn ich deine Selectanweisung umsetze.
Ersetze mal alle "len(" durch "length(". Prinzipiell heißen die Funktionen einfach immer nur ein bischen anders in den verschiedenen SQL Welten.
 

Steve6

Aktiver Benutzer
Beiträge
26
Dies funktioniert soweit ja gut:

Code:
substr(Flurstueck,1,instr(Flurstueck,'/')-1) AS Zaehler, substr(Flurstueck,(length(Flurstueck)-instr(Flurstueck,'/'))*-1) AS Nenner

Nur besteht hier das Problem, dass bei einem Flurstück ohne Nenner, der Zähler in die Nenner rutscht.

Zudem werden aus den Zahlen z.B. 160 keine 00160. Deswegen habe ich ja TO_CHAR eingesetzt.

Gruß
 

ukulele

Datenbank-Guru
Beiträge
4.394
Also in meinem Beispiel wird aus dem CHAR (1/2 muss ja CHAR sein) nie ein INT, zumindest sollte das nicht automatisch passieren. Darum kann ich auch noch Nullen als Text anfügen.

Dein Flurstück ohne Nenner arbeiten wir einfach auch mit CASE ab:

Code:
SELECT    Gemarkung,
        Flur,
        (    CASE
            WHEN    Flurstueck NOT LIKE '%/%'
            AND        length(Flurstueck) = 1
            THEN    '00' + Flurstueck
            WHEN    Flurstueck NOT LIKE '%/%'
            AND        length(Flurstueck) = 2
            THEN    '0' + Flurstueck
            WHEN    Flurstueck NOT LIKE '%/%'
            AND        length(Flurstueck) > 2
            THEN    Flurstueck
            WHEN    length(substr(Flurstueck,1,instr(Flurstueck,'/')-1)) = 1
            THEN    '00' + substr(Flurstueck,1,instr(Flurstueck,'/')-1)
            WHEN    length(substr(Flurstueck,1,instr(Flurstueck,'/')-1)) = 2
            THEN    '0' + substr(Flurstueck,1,instr(Flurstueck,'/')-1)
            ELSE    substr(Flurstueck,1,instr(Flurstueck,'/')-1)
            END ) AS Zaehler,
        (    CASE
            WHEN    Flurstueck NOT LIKE '%/%'
            THEN    NULL
-- oder        THEN    '00000'
            WHEN    length(substr(Flurstueck,(length(Flurstueck)-instr(Flurstueck,'/'))*-1)) = 1
            THEN    '0000' + substr(Flurstueck,(length(Flurstueck)-instr(Flurstueck,'/'))*-1)
            WHEN    length(substr(Flurstueck,(length(Flurstueck)-instr(Flurstueck,'/'))*-1)) = 2
            THEN    '000' + substr(Flurstueck,(length(Flurstueck)-instr(Flurstueck,'/'))*-1)
            WHEN    length(substr(Flurstueck,(length(Flurstueck)-instr(Flurstueck,'/'))*-1)) = 3
            THEN    '00' + substr(Flurstueck,(length(Flurstueck)-instr(Flurstueck,'/'))*-1)
            WHEN    length(substr(Flurstueck,(length(Flurstueck)-instr(Flurstueck,'/'))*-1)) = 4
            THEN    '0' + substr(Flurstueck,(length(Flurstueck)-instr(Flurstueck,'/'))*-1)
            ELSE    substr(Flurstueck,(length(Flurstueck)-instr(Flurstueck,'/'))*-1)
            END ) AS Nenner
FROM    tabelle
 

Steve6

Aktiver Benutzer
Beiträge
26
Hallo ukulele und Danke für deinen Beitrag. Leider gibt Oracle mir das aus:

SQL execution error, ORA-00932: Inkonsistente Datentypen: NUMBER erwartet, CHAR erhalten
 

ukulele

Datenbank-Guru
Beiträge
4.394
Das kann ich mir bei einem Select auf eine Spalte die offensichtlich char sein muss mit den angewandten Funktionen nicht erklären. Oder hast du versucht eine Spalte zu füllen die nicht char ist?
 
Werbung:

Steve6

Aktiver Benutzer
Beiträge
26
Das kann ich dir leider nicht sagen. Ich habe versucht, deinen select durchlaufen zu lassen. Das Feld Flurstueck müsste ja ein char sein.
 
Oben