Mam taki stół
Value String
-------------------
1 Cleo, Smith
Chcę rozdzielić ciąg rozdzielany przecinkami na dwie kolumny
Value Name Surname
-------------------
1 Cleo Smith
Potrzebuję tylko dwóch stałych dodatkowych kolumn
sql-server
sql-server-2008
csv
Gurru
źródło
źródło
Odpowiedzi:
źródło
WHILE
pętla (jeszcze gorzej) razem będą działać fatalnie. Poza tym jest to odpowiedź złożona tylko z kodu i nawet nie rozwiązuje problemu. Istnieją znacznie lepsze podejścia! W przypadku SQL-Server 2016+ szukajSTRING_SPLIT()
(które nie zawiera pozycji fragmentu, ogromnaJSON
porażka !) Lub naprawdę szybkiego -hacka. W przypadku starszej wersji poszukaj dobrze znanego hacka XML (szczegóły json i xml tutaj ). Lub poszukaj jednego z wielu iTVF opartych na rekurencyjnych CTE.SELECT * FROM STRING_SPLIT('John,Jeremy,Jack',',')
Twój cel można rozwiązać za pomocą następującego zapytania -
Nie ma gotowej funkcji Split na serwerze sql, więc musimy stworzyć funkcję zdefiniowaną przez użytkownika.
źródło
SELECT * FROM STRING_SPLIT('John,Jeremy,Jack',',')
a także sprawdź poniższy link w celach informacyjnych
http://jahaines.blogspot.in/2009/06/converting-delimited-string-of-values.html
źródło
CHARINDEX
plusowySUBSTRING
bałagan, przynajmniej dla mnie. :-(CONVERT(XML,'<Names><name><![CDATA[' + REPLACE(Name,',', ']]></name><name><![CDATA[') + ']]></name></name>') AS xmlname
Podstawowa odpowiedź xml jest prosta i przejrzysta
odnieś to
źródło
Myślę, że to jest fajne
źródło
Z CROSS APPLY
źródło
Istnieje wiele sposobów rozwiązania tego problemu i wiele różnych zostało już zaproponowanych. Najprościej byłoby użyć
LEFT
/SUBSTRING
i innych funkcji tekstowych, aby osiągnąć pożądany rezultat.Przykładowe dane
Korzystanie z funkcji ciągów, takich jak
LEFT
To podejście kończy się niepowodzeniem, jeśli w ciągu jest więcej 2 elementów. W takim scenariuszu możemy użyć rozdzielacza, a następnie użyć
PIVOT
lub przekonwertować ciąg na ciąg znakówXML
i użyć.nodes
do uzyskania elementów ciągu.XML
oparte na rozwiązaniu zostały szczegółowo opisane przez aads i bvr w ich rozwiązaniu.Odpowiedzi na to pytanie, które używają rozdzielacza, używają tego,
WHILE
co jest nieefektywne do rozdzielania. Sprawdź to porównanie wydajności . Jeden z najlepszych splitterów na świecieDelimitedSplit8K
, stworzony przez Jeffa Modena. Więcej na ten temat przeczytasz tutajRozdzielacz z
PIVOT
Wynik
DelimitedSplit8K
przez Jeffa Modenaźródło
Spróbuj tego (zmień wystąpienia „na” lub dowolny separator, którego chcesz użyć)
Przykładowe użycie:
źródło
W SQL Server 2016 możemy to osiągnąć za pomocą string_split:
źródło
Invalid object name 'string_split'
DECLARE @cl TINYINT; SELECT @cl = compatibility_level FROM [sys].[databases] WHERE name = 'mydb'; IF @cl < 130 BEGIN ALTER DATABASE myDb SET COMPATIBILITY_LEVEL = 130 END;
Myślę, że PARSENAME to zgrabna funkcja do użycia w tym przykładzie, jak opisano w tym artykule: http://www.sqlshack.com/parsing-and-rotating-delimited-data-in-sql-server-2012/
Funkcja PARSENAME jest logicznie zaprojektowana do analizowania czteroczęściowych nazw obiektów. Zaletą PARSENAME jest to, że nie ogranicza się do analizowania tylko czteroczęściowych nazw obiektów SQL Server - analizuje każdą funkcję lub ciąg danych, które są rozdzielone kropkami.
Pierwszy parametr to obiekt do przeanalizowania, a drugi to liczba całkowita elementu obiektu do zwrócenia. Artykuł omawia parsowanie i rotację danych rozdzielanych - firmowych numerów telefonów, ale może być również używany do parsowania danych dotyczących imienia / nazwiska.
Przykład:
W artykule opisano również użycie wyrażenia Common Table Expression (CTE) o nazwie „replaceChars” do uruchamiania PARSENAME względem wartości zastąpionych ogranicznikiem. CTE jest przydatne do zwracania tymczasowego widoku lub zestawu wyników.
Następnie funkcja UNPIVOT została użyta do konwersji niektórych kolumn na wiersze; Funkcje SUBSTRING i CHARINDEX zostały użyte do usunięcia niespójności w danych, a na końcu została użyta funkcja LAG (nowość w SQL Server 2012), która umożliwia odwoływanie się do poprzednich rekordów.
źródło
źródło
Możemy stworzyć taką funkcję
Następnie możemy oddzielić wartości CSV do odpowiednich kolumn za pomocą instrukcji SELECT
źródło
Myślę, że zadziała dla Ciebie następująca funkcja:
Najpierw musisz utworzyć funkcję w SQL. Lubię to
Możesz wywołać tę funkcję, na przykład:
Realizacja:
Wynik będzie taki:
źródło
Można użyć funkcji wycenianej w tabeli
STRING_SPLIT
, która jest dostępna tylko na poziomie zgodności 130. Jeśli poziom zgodności bazy danych jest niższy niż 130, SQL Server nie będzie w stanie znaleźć i wykonać tejSTRING_SPLIT
funkcji. Możesz zmienić poziom zgodności bazy danych za pomocą następującego polecenia:Składnia
zobacz dokumentację tutaj
źródło
Użyj funkcji Parsename ()
Wynik
źródło
Spróbuj tego:
źródło
Napotkałem podobny problem, ale złożony, a ponieważ jest to pierwszy wątek, który znalazłem w związku z tym problemem, postanowiłem opublikować swoje odkrycie. Wiem, że jest to złożone rozwiązanie prostego problemu, ale mam nadzieję, że mógłbym pomóc innym osobom, które przechodzą do tego wątku w poszukiwaniu bardziej złożonego rozwiązania. Musiałem podzielić ciąg zawierający 5 liczb (nazwa kolumny: LevelFeed) i pokazać każdą liczbę w osobnej kolumnie. na przykład: 8,1,2,2,2 powinno być wyświetlane jako:
Rozwiązanie 1: użycie funkcji XML: to rozwiązanie dla najwolniejszego rozwiązania
Rozwiązanie 2: użycie funkcji Split i Pivot. (funkcja split dzieli ciąg na wiersze z nazwą kolumny Data)
Rozwiązanie 3: użycie funkcji manipulacji na strunach - najszybsze z niewielkim marginesem względem rozwiązania 2
ponieważ levelsFeed zawiera 5 wartości łańcuchowych, potrzebowałem użyć funkcji podciągu dla pierwszego łańcucha.
Mam nadzieję, że moje rozwiązanie pomoże innym, którzy dotarli do tego wątku, szukając bardziej złożonych metod podziału na kolumny
źródło
Korzystanie z funkcji instring :)
Użyto dwóch funkcji,
1.
substring(string, position, length)
==> zwraca łańcuch od pozycji do długości2.
instr(string,pattern)
==> zwraca pozycję wzorca.Jeśli nie podamy argumentu długości w podłańcuchu, zwraca on do końca ciągu
źródło
substring(@str, 1, charindex(@sep, @str) - 1)
a następniesubstring(@str, charindex(@sep, @str) + 1, len(@str))
.Ta funkcja jest najszybsza:
Przykładowe użycie:
źródło
To zadziałało dla mnie
źródło
mój stół:
Poniższe działania powinny działać, jeśli nie ma zbyt wielu kolumn
Wynik:
źródło
to jest tak proste, możesz to zrobić za pomocą poniższego zapytania:
źródło
źródło
Możesz znaleźć rozwiązanie w funkcji zdefiniowanej przez użytkownika SQL, aby przeanalizować rozdzielany ciąg znaków (z projektu kodu ).
To jest część kodu z tej strony:
źródło
źródło
Zauważyłem, że użycie PARSENAME jak powyżej spowodowało, że każda nazwa z kropką została anulowana.
Więc jeśli w nazwie znajdował się inicjał lub tytuł, po którym występuje kropka, zwracają NULL.
Okazało się, że to działa dla mnie:
źródło
źródło
źródło
Ponownie napisałem odpowiedź powyżej i poprawiłem ją:
Przykładowe użycie:
źródło
źródło