Podzielenie kolumn separatorem w tekście

0

w jednej kolumnie mam wiersze z taką zawartością (tekst + liczby (różnej długości))
/aaaaaa/bbbbbb/cccccc/ddddddd/eeeeee

chciałbym wyżycić te dane do osobnych kolumn w jednym wierszu - separatorem jest /

jakim poleceniem to zrobić ???

1

A tych separatorów też jest rózna ilość?

UPDATE
Jaka baza? Bo postgresie jest coś takiego https://www.postgresql.org/docs/15/functions-string.html
Zwłaszcza split_part i string_to_table wydają się przydatne

0

separatorów "/" jest 5 - stała ilość., baza MSSQL. W MSSQL próbowałem split i dzielił mi ten tekst, ale w dół - czyli zwielokrotniał ilość wierszy - a ja potrzebuje jeden wiersz i 5 kolumn.

1

Pytanie - o co Ci chodzi? Bo tak nie do końca zrozumiałem.
Czy masz już te dane w bazie i chcesz je przerobić na stałe, a potem pracować już na tych 5 kolumnach, czy chcesz cały czas trzymać to w jednej kolumnie, oddzielone ukośnikiem, a jedynie je rozdzielać podczas wykonywania zapytania SELECT i w postaci rozdzielonej przesłać do aplikacji?

0

dane w bazie mają pozostać niezmienione (mam je w bazie). Potrzebuję wyciągnąć (rozbić) je SELECT-em do 5 kolumn w celu dalszej analizy.

3

A serio musisz to robić po stronie bazy?
Nie byłoby lepiej i prościej, żeby pobrać sobie po jednej linii z bazy, a potem tą linie już sobie rozdzielić na 5 części w apce?

0

Ponad 1 milion wierszy w bazie, w excelu mało user friendly - przynajmniej jak dla mnie, ale mistrzem excela nie jestem, SQL-a również jak widać, bo nie mogę sobie z tym poradzić.
Dlatego proszę o wsparcie.

1

Zmienić w locie kolumne na xml i wyciągać węzły

with v as (
Select
    kolumna
    ,convert(xml,'<r><k>'+replace(kolumna,'/','</k><k>')+'</k></r>') x
from
  Tabela
)

Select
	 *
	,x.value('/r[1]/k[2]','varchar(100)') w1 
	,x.value('/r[1]/k[3]','varchar(100)') w2
	,x.value('/r[1]/k[4]','varchar(100)') w3
	,x.value('/r[1]/k[5]','varchar(100)') w4
	,x.value('/r[1]/k[6]','varchar(100)') w5
from
   v

http://sqlfiddle.com/#!18/34ce1/6

1
hadek napisał(a):

separatorów "/" jest 5 - stała ilość., baza MSSQL. W MSSQL próbowałem split i dzielił mi ten tekst, ale w dół - czyli zwielokrotniał ilość wierszy - a ja potrzebuje jeden wiersz i 5 kolumn.

No tak.
Każda funkcja / wyrażenie SQL, która z zasady zwraca "jedną sztukę", skalar, a jest tego w realnym życiu kilka, robi to w pionie. Taki SQL jest.

Zróbmy "reductio ad absurdum". Załóżmy, że tak super funkcja split istnieje - to co miałaby zwracać? Nie może zwrócić pięciu skalarów, bo nie, i już.
Mogłaby (o ile by istniała) zwrócić SQL array (w serwerach, które posiadają tą koncepcję), ale to też cię nie interesuje, array to nie to samo, co piec skalarów ...

Post @Panczo (wydaje sie nadmiernie złożony) ale i tak ostatecznie co prezentuje ? Pięć wyrażeń na liście select . Po prostu "nie chce być inaczej"
Tą samą ideę pięciu wyrażeń można inaczej zaimplementować, jako piec substringów czy coś podobnego. Inna implementacja, ta sama filozofia rozwiązania

cerrato napisał(a):

A serio musisz to robić po stronie bazy?
Nie byłoby lepiej i prościej, żeby pobrać sobie po jednej linii z bazy, a potem tą linie już sobie rozdzielić na 5 części w apce?

Dokładnie.

hadek napisał(a):

w jednej kolumnie mam wiersze z taką zawartością (tekst + liczby (różnej długości))
/aaaaaa/bbbbbb/cccccc/ddddddd/eeeeee

To teraz już wiesz, że taki projekt bazy jest d/d, i następnej tak nie zrobisz.

0

@ZrobieDobrze - jeśli uważasz,że w SQL nie da się tego zrealizować, to wystarczyło napisać to w jednym zdaniu.

To teraz już wiesz, że taki projekt bazy jest d/d, i następnej tak nie zrobisz - skąd te wnioski, że to mój projekt ?

1

@ZrobieDobrze:
Troche słabe zaprzeczenie:

Zróbmy "reductio ad absurdum". Załóżmy, że tak super funkcja split istnieje - to co miałaby zwracać? Nie może zwrócić pięciu skalarów, bo nie, i już.

A dlaczego nie może?

CREATE FUNCTION Split(@s varchar(150))
    RETURNS @scalar TABLE (
        s1 VARCHAR(50),
        s2 VARCHAR(50),
        s3 VARCHAR(50),
        s4 VARCHAR(50),
        s5 VARCHAR(50)
    )
AS
BEGIN
    DECLARE @x xml
    set @x = convert(xml,'<r><k>'+replace(@s,'/','</k><k>')+'</k></r>')
    INSERT INTO @scalar
    values (
		@x.value('/r[1]/k[2]','varchar(100)')  
		,@x.value('/r[1]/k[3]','varchar(100)')
		,@x.value('/r[1]/k[4]','varchar(100)')
		,@x.value('/r[1]/k[5]','varchar(100)')
		,@x.value('/r[1]/k[6]','varchar(100)')
      )
    RETURN
END;

I wtedy:

select *
from Tabela
cross apply split(Kolumna)

Mamy oczekiwany wynik "w poziomie"

Zresztą jeżeli wyjdziemy z SQL Servera:

SPLIT_PART.

Tak oczywiście zgodzę się z tobą, że nadal trzeba napisać pięć wyrażeń, ale nie zaprzeczaj, że takie funkcje nie istnieją.

0

@Panczo:

No tak ...
W tamtym poście powinienem sobie przywołać choćby klasyczną procedurę SQL, która zwraca nie SQL array a SQL Table

Panczo napisał(a):

Tak oczywiście zgodzę się z tobą, że nadal trzeba napisać pięć wyrażeń, ale nie zaprzeczaj, że takie funkcje nie istnieją.

Pewien doktoryzując się należało postawić nie tezę "załóżmy że istnieją" a "istnieją i są przydatne w oczekiwany sposób"

ps. Nie ma innego sposobu podzielić, niż przechodząc przez XML ? Trochę strzelanie z armaty
Mam przed oczami (w dialekcie MS-SQL) Substring w połączeniu z Charindex(...'/'..) , doprowadzi do skutku, żmudne, mało eleganckie

0

@Panczo: sprawdziłem Twoją propozycję i jak robię select-a dla pierwszych 1000 wierszy to jest ok - dodatkowe kolumny się tworzą etc. Natomiast jak wykonuję to samo dla całej dabeli, to otrzymuję: Msg 9421, Level 16, State 1, Line 42
XML parsing: line 1, character 180, illegal name character

0

@ZrobieDobrze: można oczywiście bawić się w charindex, ale wbrew pozorom jak pojawi się coś nieoczekiwanego w parsowanym ciąg to wywali błędem i wyrażenie które będzie na to odporne będzie strasznie toporne.
W teorii można użyć string_split, ale dopiero od wersji 2022 dodali parametr który zwróci w wyniku pozycję w stringu, a tak nie ma gwarancji w jakiej kolejności to zostanie zwrócone.

@hadek jeżeli masz w tym polu któryś z tych znaków: <, >, &, ', " to musisz je zamienić https://stackoverflow.com/questions/1091945/what-characters-do-i-need-to-escape-in-xml-documents

0

@ZrobieDobrze: dużo pomogło, ale mam problem z "' represents ' - nie mogę wyszukać ' i potem zrobić update - pozostałe zrobiłem i jest dużo lepiej, ale wisi mi jeszcze ten znak

0
Replace(kolumna,'''','&apos;')

1 użytkowników online, w tym zalogowanych: 0, gości: 1