Eu tenho uma tabela SQL como esta:
| SomeID | OtherID | Data
+----------------+-------------+-------------------
| abcdef-..... | cdef123-... | 18,20,22
| abcdef-..... | 4554a24-... | 17,19
| 987654-..... | 12324a2-... | 13,19,20
existe uma consulta em que eu possa executar uma consulta como SELECT OtherID, SplitData WHERE SomeID = 'abcdef-.......'
essa retorna linhas individuais, assim:
| OtherID | SplitData
+-------------+-------------------
| cdef123-... | 18
| cdef123-... | 20
| cdef123-... | 22
| 4554a24-... | 17
| 4554a24-... | 19
Dividir basicamente meus dados na vírgula em linhas individuais?
Estou ciente de que armazenar uma comma-separated
string em um banco de dados relacional parece idiota, mas o caso de uso normal no aplicativo consumidor torna isso realmente útil.
Não quero fazer a divisão no aplicativo, pois preciso de paginação; portanto, queria explorar as opções antes de refatorar o aplicativo inteiro.
É SQL Server 2008
(não R2).
sql-server
tsql
split
comma
Michael Stum
fonte
fonte
Respostas:
Você pode usar as maravilhosas funções recursivas do SQL Server:
Tabela de exemplo:
A pergunta
Resultado
fonte
Data
devarchar(max)
paravarchar(4000)
, por exemplocreate table Testdata(SomeID int, OtherID int, Data varchar(4000))
?OPTION (maxrecursion 0)
Finalmente, a espera terminou com o SQL Server 2016 . Eles introduziram a função String dividida
STRING_SPLIT
:Todos os outros métodos para dividir seqüências de caracteres como XML, tabela Tally, loop while, etc., foram surpreendidos por essa
STRING_SPLIT
função.Aqui está um excelente artigo com comparação de desempenho: Surpresas e premissas de desempenho: STRING_SPLIT .
Para versões mais antigas, o uso da tabela de contagem aqui é uma função de cadeia de divisão (melhor abordagem possível)
Referido de Tally OH! Uma função aprimorada de “CSV Splitter” do SQL 8K
fonte
value
, nãoSplitData
.Verifique isto
fonte
fonte
CROSS APPLY
, isso é meio útil!select t.OtherID, x.* from testData t cross apply (select item as Data from dbo.Split(t.Data,',') ) x
A partir de fevereiro de 2016 - veja o exemplo da tabela TALLY - muito provavelmente superará meu TVF abaixo, a partir de fevereiro de 2014. Mantendo a postagem original abaixo para posteridade:
Muito código repetido para o meu gosto nos exemplos acima. E não gosto do desempenho de CTEs e XML. Além disso, um explícito
Id
para que os consumidores específicos de pedidos possam especificar umaORDER BY
cláusula.fonte
É bom ver que ele foi resolvido na versão de 2016, mas para todos aqueles que não estão nessa, aqui estão duas versões generalizadas e simplificadas dos métodos acima.
O método XML é mais curto, mas é claro que requer a string para permitir o xml-trick (sem caracteres 'ruins').
Método XML:
Método recursivo:
Função em ação
MÉTODO XML 2: Compatível com Unicode 😀 (cortesia de Max Hodges)
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);
fonte
Consulte abaixo TSQL. A função STRING_SPLIT está disponível apenas no nível de compatibilidade 130 e acima.
TSQL:
RESULTADO:
Cor
vermelho azul verde amarelo preto
fonte
Muito tarde, mas tente isso:
Então estávamos tendo o seguinte: tbl_Sample:
Depois de executar esta consulta:
Obrigado!
fonte
STRING_SPLIT
é bacana, mas requer o SQL Server 2016. docs.microsoft.com/en-us/sql/t-sql/functions/…fonte
com apenas pequenas modificações para a consulta acima ...
fonte
Eu sempre uso o método XML. Certifique-se de usar XML válido. Eu tenho duas funções para converter entre XML e texto válidos. (Costumo retirar os retornos de carro, pois geralmente não preciso deles.
fonte
SELECT (SELECT '<&> blah' + CHAR(13)+CHAR(10) + 'next line' FOR XML PATH(''))
Função
Caso de uso
Ou apenas uma seleção com vários resultados
fonte
Abaixo trabalha no sql server 2008
Obterá todo o produto cartesiano com as colunas da tabela de origem mais "itens" da tabela dividida.
fonte
Você pode usar a seguinte função para extrair dados
fonte