Mam taką tabelę SQL:
| SomeID | OtherID | Data
+----------------+-------------+-------------------
| abcdef-..... | cdef123-... | 18,20,22
| abcdef-..... | 4554a24-... | 17,19
| 987654-..... | 12324a2-... | 13,19,20
czy istnieje zapytanie, w którym mogę wykonać takie zapytanie, SELECT OtherID, SplitData WHERE SomeID = 'abcdef-.......'
które zwraca pojedyncze wiersze, takie jak to:
| OtherID | SplitData
+-------------+-------------------
| cdef123-... | 18
| cdef123-... | 20
| cdef123-... | 22
| 4554a24-... | 17
| 4554a24-... | 19
Zasadniczo podzielisz moje dane przecinkiem na poszczególne wiersze?
Wiem, że przechowywanie comma-separated
łańcucha w relacyjnej bazie danych brzmi głupio, ale normalny przypadek użycia w aplikacji konsumenckiej sprawia, że jest to naprawdę pomocne.
Nie chcę dokonywać podziału w aplikacji, ponieważ potrzebuję stronicowania, więc chciałem zbadać opcje przed refaktoryzacją całej aplikacji.
To SQL Server 2008
(nie R2).
sql-server
tsql
split
comma
Michael Stum
źródło
źródło
Odpowiedzi:
Możesz użyć wspaniałych funkcji rekurencyjnych z SQL Server:
Przykładowa tabela:
Zapytanie
Wynik
źródło
Data
zvarchar(max)
navarchar(4000)
np.create table Testdata(SomeID int, OtherID int, Data varchar(4000))
?OPTION (maxrecursion 0)
Wreszcie oczekiwanie dobiegło końca dzięki SQL Server 2016 . Wprowadzili funkcję Split string
STRING_SPLIT
:Wszystkie inne metody dzielenia ciągów znaków, takie jak XML, tabela Tally, pętla while itp. Zostały zdmuchnięte przez tę
STRING_SPLIT
funkcję.Oto doskonały artykuł z porównaniem wydajności: Niespodzianki i założenia dotyczące wydajności: STRING_SPLIT .
W starszych wersjach użycie tabeli podsumowań jest jedną funkcją podziału łańcucha (najlepsze możliwe podejście)
Polecony przez Tally OH! Ulepszona funkcja „CSV Splitter” SQL 8K
źródło
value
nieSplitData
.Sprawdź to
źródło
źródło
CROSS APPLY
, jest to przydatne!select t.OtherID, x.* from testData t cross apply (select item as Data from dbo.Split(t.Data,',') ) x
W lutym 2016 r. - patrz przykład tabeli TALLY - najprawdopodobniej przewyższy moją TVF poniżej, od lutego 2014 r. Zachowanie oryginalnego postu dla potomności:
Zbyt dużo powtarzającego się kodu dla moich upodobań w powyższych przykładach. I nie podoba mi się wydajność CTE i XML. Również wyraźne
Id
, aby konsumenci, którzy są specyficzni dla zamówienia, mogli określićORDER BY
klauzulę.źródło
Miło widzieć, że zostało to rozwiązane w wersji 2016, ale dla wszystkich tych, których nie ma, oto dwie uogólnione i uproszczone wersje powyższych metod.
Metoda XML jest krótsza, ale oczywiście wymaga ciągu, aby zezwolić na sztuczkę xml (bez „złych” znaków).
Metoda XML:
Metoda rekurencyjna:
Funkcja w akcji
XML-METHOD 2: Unicode Friendly 😀 (Dodatek udostępniony dzięki uprzejmości Maxa Hodgesa)
create function dbo.splitString(@input nVarchar(max), @Splitter nVarchar(99)) returns table as Return SELECT Split.a.value('.', 'NVARCHAR(max)') AS Data FROM ( SELECT CAST ('<M>' + REPLACE(@input, @Splitter, '</M><M>') + '</M>' AS XML) AS Data ) AS A CROSS APPLY Data.nodes ('/M') AS Split(a);
źródło
Zobacz poniżej TSQL. Funkcja STRING_SPLIT jest dostępna tylko na poziomie zgodności 130 i wyższym.
TSQL:
WYNIK:
Kolor
czerwony niebieski zielony żółty czarny
źródło
Bardzo późno, ale wypróbuj to:
Mieliśmy to: tbl_Sample:
Po uruchomieniu tego zapytania:
Dzięki!
źródło
STRING_SPLIT
jest fajny, ale wymaga SQL Server 2016. docs.microsoft.com/en-us/sql/t-sql/functions/...źródło
z niewielką modyfikacją powyższego zapytania ...
źródło
Zawsze używam metody XML. Upewnij się, że używasz VALID XML. Mam dwie funkcje do konwersji między poprawnym XML a tekstem. (Staram się rozbierać zwroty karetki, ponieważ zwykle ich nie potrzebuję.
źródło
SELECT (SELECT '<&> blah' + CHAR(13)+CHAR(10) + 'next line' FOR XML PATH(''))
Funkcjonować
Przypadek użycia
Lub po prostu wybierz z wieloma zestawami wyników
źródło
Poniżej działa na serwerze SQL 2008
Otrzyma cały produkt kartezjański z kolumnami tabeli początkowej oraz „elementami” podzielonej tabeli.
źródło
Możesz użyć następującej funkcji do wyodrębnienia danych
źródło