SQL: Zahlen- und Buchstabendaten trennen

Aus DBWiki
Wechseln zu: Navigation, Suche

Zurück zur Übersicht



Verfügt der SQL-Dialekt über eine translate()-Funktion, lässt sich die Aufgabe damit recht bequem lösen. Im anderen Fall bietet sich eine Lösung über Reguläre Ausdrücke an.


Hinweis für Access-Anwender
Um die folgende Abfrage selbst testen zu können, müssen die Tabellen der Übungsdatenbank vorhanden sein.


Um unsere (unglückliche) Ausgangslage zu simulieren, verwenden wir folgende Auswahlabfrage vw_daten:

SELECT ma_name & gehalt AS daten
FROM   mitarbeiter

In Access können Reguläre Ausdrücke in VBA über einen Verweis auf Microsoft VBScript Regular Expressions 5.5 zur Verfügung gestellt werden. Das nachfolgende VBA-Modul nutzt jedoch Late Binding, und kommt deshalb ohne zusätzlichen Verweis aus.

Private mRE As Object
 
Public Function GetMaName(Data As Variant) As Variant
   Const RE_PATTERN As String = "^[A-Za-zÄÖÜäöüß]+"
 
   Dim Subject      As String
 
   If mRE Is Nothing Then Set mRE = CreateObject("VBScript.RegExp")
 
   mRE.Pattern = RE_PATTERN
   Subject = Nz(Data)
   If mRE.Test(Subject) Then
      GetMaName = mRE.Execute(Subject)(0)
   Else
      GetMaName = Null
   End If
End Function
 
Public Function GetGehalt(Data As Variant) As Variant
   Const RE_PATTERN As String = "\d+$"
 
   Dim Subject      As String
 
   If mRE Is Nothing Then Set mRE = CreateObject("VBScript.RegExp")
 
   mRE.Pattern = RE_PATTERN
   Subject = Nz(Data)
   If mRE.Test(Subject) Then
      GetGehalt = mRE.Execute(Subject)(0)
   Else
      GetGehalt = Null
   End If
End Function

Diese beiden Funktionen können dann in einer Abfrage verwendet werden, um ma_name und gehalt zu trennen.

SELECT daten,
       GetMaName( daten ) AS ma_name,
       CLng( GetGehalt( daten ) ) AS gehalt
FROM vw_daten

Und das wird von der Abfrage ausgegeben:

daten ma_name gehalt
Schmidt800 Schmidt 800
Allard1600 Allard 1600
Wecker1250 Wecker 1250
Johann2975 Johann 2975
Mertens1250 Mertens 1250
Blank2850 Blank 2850
Kühne2450 Kühne 2450
Scheidt3000 Scheidt 3000
König5000 König 5000
Dreher1500 Dreher 1500
Adam1100 Adam 1100
Jakobs950 Jakobs 950
Fuhrmann3000 Fuhrmann 3000
Müller1300 Müller 1300



In PostgreSQL könnte man z. B. eine der beiden folgenden Abfragen verwenden:

SELECT daten,
       translate( daten, '0123456789', '' ) AS ma_name,
       translate( LOWER( daten ), 'abcdefghijklmnopqrstuvwxyzäöüß', '' )::INTEGER AS gehalt
FROM vw_daten
SELECT daten,
       SUBSTRING( daten, '^[a-zA-ZäöüÄÖÜß]+' ) AS ma_name,
       SUBSTRING( daten, '\d+$' )::INTEGER AS gehalt
FROM vw_daten

Beide Versionen sind diesem DBFiddle zu sehen.



Zurück zur Übersicht