Dividere una colonna in più righe

Qualcuno può dirmi come farlo? Una colonna nella mia tabella, in alcuni casi, contiene valori separati da virgola. Se lo fa, ho bisogno di creare nuove righe per questi valori.

Inoltre, ad esempio, una tabella contiene 1 riga e 4 colonne Col1 | Col2 | Col3 | Col4 con i seguenti valori A | B | C | 1,2,3 rispettivamente. Quindi, Col4 contiene la stringa “1,2,3” e ho bisogno di scomporre i valori separati da virgole e metterli su linee per far sì che la tabella contenga 1 riga dove 1 2 e 3 sono su linee di loro in Col4.

Penso che tu possa fare questo:

SELECT T.id, RIGHT(LEFT(T.csv,Number-1), CHARINDEX(',',REVERSE(LEFT(','+T.csv,Number-1)))) FROM master..spt_values, your_table T WHERE Type = 'P' AND Number BETWEEN 1 AND LEN(T.csv)+1 AND (SUBSTRING(T.csv,Number,1) = ',' OR SUBSTRING(T.csv,Number,1) = '') 

Il codice è stato spudoratamente rubato da questo sito .

Puoi scrivere una funzione di tabella e unirti alla colonna con CROSS APPLY . Ecco la mia versione.

 CREATE FUNCTION dbo.Splitter(@text nvarchar(max), @separator nvarchar(100)) RETURNS @result TABLE (i int, value nvarchar(max)) AS BEGIN DECLARE @i int DECLARE @offset int SET @i = 0 WHILE @text IS NOT NULL BEGIN SET @i = @i + 1 SET @offset = charindex(@separator, @text) INSERT @result SELECT @i, CASE WHEN @offset > 0 THEN LEFT(@text, @offset - 1) ELSE @text END SET @text = CASE WHEN @offset > 0 THEN SUBSTRING(@text, @offset + LEN(@separator), LEN(@text)) END END RETURN END 

Un’altra delle molte funzioni di divisione delle stringhe. Questo è simile alla risposta di @Byron Whitlock, ma invece di usare master..spt_values ​​usa un cte per generare una tabella di numeri. SQL Server 2005 in poi.

 CREATE TABLE dbo.Table1 ( Col1 CHAR(1), Col2 CHAR(1), Col3 CHAR(1), Col4 VARCHAR(50) ) GO INSERT INTO dbo.Table1 VALUES ('A','B','C','1,2,3') GO SELECT * FROM dbo.Table1; GO WITH L0 AS(SELECT 1 AS c UNION ALL SELECT 1), L1 AS(SELECT 1 AS c FROM L0 AS A, L0 AS B), L2 AS(SELECT 1 AS c FROM L1 AS A, L1 AS B), L3 AS(SELECT 1 AS c FROM L2 AS A, L2 AS B), Numbers AS(SELECT ROW_NUMBER() OVER(ORDER BY c) AS n FROM L3) SELECT Col1, Col2, Col3, LTRIM(RTRIM(SUBSTRING(valueTable.Col4, nums.n, charindex(N',', valueTable.Col4 + N',', nums.n) - nums.n))) AS [Value] FROM Numbers AS nums INNER JOIN dbo.Table1 AS valueTable ON nums.n <= CONVERT(int, LEN(valueTable.Col4)) AND SUBSTRING(N',' + valueTable.Col4, n, 1) = N',' 

So che questo è un post più vecchio ma ho pensato di aggiungere un aggiornamento. Tally Table e cectTally table splitter hanno tutti un grosso problema. Usano delimitatori concatenati e uccidono la loro velocità quando gli elementi si allargano e le stringhe si allungano.

Ho risolto il problema e ho scritto un articolo su di esso che può essere trovato al seguente URL. http://www.sqlservercentral.com/articles/Tally+Table/72993/

Ti dirò anche che un individuo di nome “Peter” ha apportato un miglioramento anche a quel codice (nella discussione per l’articolo). L’articolo è ancora interessante e aggiornerò gli allegati con i miglioramenti di Peter nei prossimi giorni o due. Tra il mio miglioramento e il tweek di Peter, non credo che troverai una soluzione T-SQL più veloce per la divisione di VARCHAR (8000). Ho anche risolto il problema di questa razza di splitter per VARCHAR (MAX) e sto anche scrivendo un articolo per questo.