Divida una columna en varias filas

¿Alguien puede decirme cómo lograr esto? Una columna en mi tabla, en algunos casos, contiene valores separados por comas. Si lo hace, necesito crear nuevas filas para estos valores.

Además, como ejemplo, una tabla contiene 1 fila y 4 columnas Col1 | Col2 | Col3 | Col4 con los siguientes valores A | B | C | 1,2,3 respectivamente. Entonces, Col4 contiene la cadena ‘1,2,3’ y necesito dividir los valores separados por comas y colocarlos en líneas propias para que la tabla contenga 1 filas donde 1 2 y 3 están en líneas propias en Col4.

Creo que puedes hacer esto:

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) = '') 

El código fue descaradamente robado de este sitio .

Puede escribir una función de tabla y unir su columna con CROSS APPLY . Aquí está mi versión.

 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 

Otra de las muchas funciones de división de cuerdas que hay. Esto es similar a la respuesta de @Byron Whitlock, pero en lugar de usar master..spt_values ​​usa una cte para generar una tabla de números. SQL Server 2005 en adelante.

 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',' 

Sé que esta es una publicación anterior, pero pensé en agregar una actualización. Los divisores basados ​​en tablas Tally Table y cteTally tienen todos un problema importante. Usan delimitadores concatenados y eso mata su velocidad cuando los elementos se hacen más amplios y las cadenas se hacen más largas.

Solucioné ese problema y escribí un artículo sobre él que se puede encontrar en la siguiente URL. http://www.sqlservercentral.com/articles/Tally+Table/72993/

También le diré que un tipo con el nombre de “Peter” hizo una mejora incluso a ese código (en la discusión del artículo). El artículo sigue siendo interesante y voy a actualizar los archivos adjuntos con las mejoras de Peter en el próximo día o dos. Entre mi mejora principal y la tweek que hizo Peter, no creo que encuentres una solución T-SQL-Only más rápida para dividir VARCHAR (8000). También resolví el problema para esta clase de divisores para VARCHAR (MAX) y también estoy escribiendo un artículo para eso.