Tengo una mesa como esta
Value String
-------------------
1 Cleo, Smith
Quiero separar la cadena delimitada por comas en dos columnas
Value Name Surname
-------------------
1 Cleo Smith
Solo necesito dos columnas adicionales fijas
sql-server
sql-server-2008
csv
Gurru
fuente
fuente
Respuestas:
fuente
WHILE
bucle (incluso peor) juntos funcionarán terriblemente. Además, esta es una respuesta de solo código y ni siquiera resuelve el problema. ¡Hay enfoques mucho mejores! Para SQL-Server 2016+, busqueSTRING_SPLIT()
(que no lleva la posición del fragmento, ¡un gran error!) O elJSON
truco realmente rápido . Para versiones anteriores, busque el conocido hack XML (detalles json y xml aquí ). O busque uno de los iTVF de mayo basados en CTE recursivos.SELECT * FROM STRING_SPLIT('John,Jeremy,Jack',',')
Su propósito puede resolverse mediante la siguiente consulta:
No hay una función Split lista para usar en el servidor SQL, por lo que necesitamos crear una función definida por el usuario.
fuente
SELECT * FROM STRING_SPLIT('John,Jeremy,Jack',',')
y también consulte el siguiente enlace para referencia
http://jahaines.blogspot.in/2009/06/converting-delimited-string-of-values.html
fuente
CHARINDEX
másSUBSTRING
, al menos para mí. :-(CONVERT(XML,'<Names><name><![CDATA[' + REPLACE(Name,',', ']]></name><name><![CDATA[') + ']]></name></name>') AS xmlname
la respuesta base de xml es simple y limpia
referir esto
fuente
Creo que esto es genial
fuente
Con APLICACIÓN CRUZADA
fuente
Hay varias formas de resolver esto y ya se han propuesto muchas formas diferentes. Lo más sencillo sería usar
LEFT
/SUBSTRING
y otras funciones de cadena para lograr el resultado deseado.Data de muestra
Usando funciones de cadena como
LEFT
Este enfoque falla si hay más 2 elementos en una cadena. En tal escenario, podemos usar un divisor y luego usar
PIVOT
o convertir la cadena en unXML
y usar.nodes
para obtener elementos de cadena.XML
La solución basada ha sido detallada por aads y bvr en su solución.Las respuestas a esta pregunta que usan divisor, todo uso
WHILE
que es ineficiente para dividir. Verifique esta comparación de rendimiento . Uno de los mejores divisores esDelimitedSplit8K
creado por Jeff Moden. Puedes leer más sobre esto aquíSplitter con
PIVOT
Salida
DelimitedSplit8K
por Jeff Modenfuente
Pruebe esto (cambie las instancias de '' a ',' o cualquier delimitador que quiera usar)
Ejemplo de uso:
fuente
Con SQL Server 2016 podemos usar string_split para lograr esto:
fuente
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;
Creo que PARSENAME es la función ordenada para usar en este ejemplo, como se describe en este artículo: http://www.sqlshack.com/parsing-and-rotating-delimited-data-in-sql-server-2012/
La función PARSENAME está diseñada lógicamente para analizar nombres de objetos de cuatro partes. Lo bueno de PARSENAME es que no se limita a analizar solo los nombres de objetos de cuatro partes de SQL Server: analizará cualquier función o datos de cadena que estén delimitados por puntos.
El primer parámetro es el objeto a analizar, y el segundo es el valor entero de la pieza del objeto a devolver. El artículo trata sobre el análisis y la rotación de datos delimitados: números de teléfono de la compañía, pero también se puede utilizar para analizar datos de nombre / apellido.
Ejemplo:
El artículo también describe el uso de una expresión de tabla común (CTE) llamada 'replaceChars', para ejecutar PARSENAME contra los valores reemplazados por delimitador. Un CTE es útil para devolver una vista temporal o un conjunto de resultados.
Después de eso, la función UNPIVOT se ha utilizado para convertir algunas columnas en filas; Las funciones SUBSTRING y CHARINDEX se han utilizado para limpiar las inconsistencias en los datos, y la función LAG (nueva para SQL Server 2012) se ha utilizado al final, ya que permite la referencia de registros anteriores.
fuente
fuente
Podemos crear una función como esta
Luego podemos separar los valores CSV en nuestras columnas respectivas usando una instrucción SELECT
fuente
Creo que la siguiente función funcionará para usted:
Primero debe crear una función en SQL. Me gusta esto
Puede llamar a esta función, así:
Implementación:
El resultado será así:
fuente
Puede usar una función con valores de tabla
STRING_SPLIT
, que está disponible solo bajo el nivel de compatibilidad 130. Si el nivel de compatibilidad de su base de datos es inferior a 130, SQL Server no podrá encontrar y ejecutar laSTRING_SPLIT
función. Puede cambiar un nivel de compatibilidad de la base de datos con el siguiente comando:Sintaxis
ver documentación aquí
fuente
Usar la función Parsename ()
Resultado
fuente
Prueba esto:
fuente
Encontré un problema similar pero complejo y dado que este es el primer hilo que encontré con respecto a ese problema, decidí publicar mi hallazgo. Sé que es una solución compleja a un problema simple, pero espero poder ayudar a otras personas que buscan este hilo en busca de una solución más compleja. Tuve que dividir una cadena que contenía 5 números (nombre de columna: levelFeed) y mostrar cada número en una columna separada. por ejemplo: 8,1,2,2,2 debe mostrarse como:
Solución 1: uso de funciones XML: esta solución para la solución más lenta con diferencia
Solución 2: usando la función Split y pivote. (la función de división divide una cadena en filas con el nombre de columna Datos)
Solución 3: uso de funciones de manipulación de cadenas: más rápido por un pequeño margen sobre la solución 2
Dado que nivelesFeed contiene 5 valores de cadena, necesitaba usar la función de subcadena para la primera cadena.
Espero que mi solución ayude a otros que llegaron a este hilo en busca de métodos de división en columnas más complejos
fuente
Usando la función instring :)
Usó dos funciones,
1.
substring(string, position, length)
==> devuelve una cadena desde la posición a la longitud2.
instr(string,pattern)
==> devuelve la posición del patrón.Si no proporcionamos un argumento de longitud en la subcadena, regresa hasta el final de la cadena
fuente
substring(@str, 1, charindex(@sep, @str) - 1)
seguido desubstring(@str, charindex(@sep, @str) + 1, len(@str))
.Esta función es más rápida:
Ejemplo de uso:
fuente
Esto funciono para mi
fuente
mi mesa:
Lo siguiente debería funcionar si no hay demasiadas columnas
Resultado:
fuente
es tan fácil que puede tomarlo a continuación:
fuente
fuente
Puede encontrar útil la solución en la función definida por el usuario de SQL para analizar una cadena delimitada (de The Code Project ).
Esta es la parte del código de esta página:
fuente
fuente
Descubrí que el uso de PARSENAME como se mencionó anteriormente causó que se anulara cualquier nombre con un punto.
Entonces, si había una inicial o un título en el nombre seguido de un punto, devuelven NULL.
Encontré que esto funcionó para mí:
fuente
fuente
fuente
Reescribí una respuesta anterior y la mejoré:
Ejemplo de uso:
fuente
fuente