String Operation auf Spalte nach Trennzeichen

Apex5

Neuer Benutzer
Beiträge
1
Hallo

leider scheitere ich bei einer String-Operation auf eine Datenbankspalte.
Es handelt sich um eine MS SQL Datenbank eines Hersteller-Werkzeugs zur Verwaltung von Client-Daten.

Nun habe ich folgendes als Ergebnis aus der Tabelle 'PrintersLocal':
Code:
USBPRINT\EPSON-2730DN\6&42D8453&0&USB001
USBPRINT\EPSON-9500\6&2B7A5B4&1&USB001
USBPRINT\EPSON-D600\8&1E6CFC1B&0&USB001
USBPRINT\EPSON-D610\8&24165EF3&0&USB001
USBPRINT\EPSON-D630\8&257FDE1&0&USB001
USBPRINT\EPSON-D635\8&26C6754F&0&USB006
USBPRINT\EPSON-D800\8&26C6754F&1&USB001

Die interessanten Daten, die ich benötige sind die Werte EPSON-2730DN oder EPSON-9500 usw.

Mein Versuch mit einem String-Split und dem Trennzeichen '\' sieht so aus:

PHP:
SELECT value
FROM PrintersLocal
    CROSS APPLY STRING_SPLIT(USBID, '\');

Damit bekomme ich alle Werte der Spalte aus der Tabelle aufgeteilt, aber ich habe nun zu viele "uninteressante" Daten, die ich nicht brauche.
Gibt es einen besseren, eleganteren Ansatz? :(

Danke
 
Werbung:
in PG würde ich es so lösen:

Code:
test=*# select * from t;
                    t                     
------------------------------------------
 USBPRINT\EPSON-2730DN\6&42D8453&0&USB001
 USBPRINT\EPSON-9500\6&2B7A5B4&1&USB001
 USBPRINT\EPSON-D600\8&1E6CFC1B&0&USB001
 USBPRINT\EPSON-D610\8&24165EF3&0&USB001
 USBPRINT\EPSON-D630\8&257FDE1&0&USB001
 USBPRINT\EPSON-D635\8&26C6754F&0&USB006
 USBPRINT\EPSON-D800\8&26C6754F&1&USB001
(7 rows)

test=*# select *, (regexp_split_to_array(t,'\\'))[2] from t;
                    t                     | regexp_split_to_array
------------------------------------------+-----------------------
 USBPRINT\EPSON-2730DN\6&42D8453&0&USB001 | EPSON-2730DN
 USBPRINT\EPSON-9500\6&2B7A5B4&1&USB001   | EPSON-9500
 USBPRINT\EPSON-D600\8&1E6CFC1B&0&USB001  | EPSON-D600
 USBPRINT\EPSON-D610\8&24165EF3&0&USB001  | EPSON-D610
 USBPRINT\EPSON-D630\8&257FDE1&0&USB001   | EPSON-D630
 USBPRINT\EPSON-D635\8&26C6754F&0&USB006  | EPSON-D635
 USBPRINT\EPSON-D800\8&26C6754F&1&USB001  | EPSON-D800
(7 rows)

test=*#

keine Ahnung, ob das in M$SQL geht ...
 
Werbung:
Hallo Apex5,

so tolle Sachen wie "array" gibt es im SQL Server leider nicht.
Daher finde ich die Lösung von Andreas (und PG) echt cool - danke dafür. (Man kommt ja oft nicht auf den Gedanken, den andere Systeme verfolgen, weil man es einfach von dem System, mit dem man allgemein arbeitet, nicht kennt!)

Der Array-Gedanke hat den Vorteil, dass man tatsächlich den SPLIT innerhalb einer Zeile durchführt - was der SQL-Server so nicht kann.
Dafür müsste man recht komplexe String-Auswertungen vornehmen.
Die Funktion STRING_SPLIT gibt jedes Trenn-Ergebnis in einer eigenen Zeile zurück - was natürlich auch von Vorteil sein kann - je nach Anforderung.
Das Ergebnis kann man dann aber ja wieder zusammenfassen und in eine Zeile bringen.

Ich habe da mal ein Beispiel gemacht. Wenn deine Quelltabelle schon eine ID hat, kann der erste Schritt, also die erste CTE entfallen. Mit dieser gebe ich jeder Zeile nur eine Nummer.
In der zweiten CTE nummeriere ich dann die Zeilen aus dem Split-Ergebnis, die sich aus der Trennung einer Spalte in der Quell-Zeile ergeben.
Mit der PIVOT-Funktion bringe ich es dann wieder in eine Form, in der die Daten wieder wie aus der Quelle mit einem Datensatz, aber mit den entsprechenden Spalten des Split aus dem String enthalten sind.

Code:
IF OBJECT_ID('TempDB..#a') IS NOT NULL DROP TABLE #a
CREATE TABLE #a
(
    Wert varchar(255)
)

INSERT INTO #a (Wert)
VALUES
('USBPRINT\EPSON-2730DN\6&42D8453&0&USB001'),
('USBPRINT\EPSON-9500\6&2B7A5B4&1&USB001'),
('USBPRINT\EPSON-D600\8&1E6CFC1B&0&USB001'),
('USBPRINT\EPSON-D610\8&24165EF3&0&USB001'),
('USBPRINT\EPSON-D630\8&257FDE1&0&USB001'),
('USBPRINT\EPSON-D635\8&26C6754F&0&USB006'),
('USBPRINT\EPSON-D800\8&26C6754F&1&USB001');


;WITH cte_nr
AS
(
    SELECT *,
    ROW_NUMBER() OVER (ORDER BY (CASE WHEN Wert IS NOT NULL THEN 1 ELSE 0 END)) as Nr
    FROM #a
)
,cte_arr_nr
AS
(
    SELECT *,
    ROW_NUMBER() OVER (PARTITION BY Nr ORDER BY Nr) as arr_nr
    FROM cte_nr
    CROSS APPLY string_split(Wert, '\')
)


SELECT Nr, Wert, [1] AS [Art], [2] AS [Typ], [3] AS [Anschluss]
FROM  
(SELECT Nr, arr_nr, value , Wert
FROM cte_arr_nr) p
PIVOT
(
MAX (value)
FOR arr_nr IN
( [1], [2], [3])
) AS pvt

Viele Grüße,
Tommi
 
Zurück
Oben