String_Split usando SQL para separar columna por comas

Estoy tratando de dividir una cadena de texto usando el ','. El texto en cuestión es nuestro utm parámetros y parece algo así:

{\""medium\"":\""cpc\"",\""source\"":\""google\"",\""term\"":\""virtual cocktail making classes\"",\""campaign\"":\""virtual-events\""}

La idea es que termino con cuatro columnas: Media, Fuente, Term y Campaña. Esto es lo que he intentado hasta ahora pero sigue recibiendo un error de sintaxis cerca APPLY.


(SELECT  id, VALUE
, ROW_NUMBER() OVER(PARTITION by id ORDER BY id) AS "RowNum"
FROM seodata
CROSS APPLY
string_split(utmparams,',')
)

SELECT id,
[1] AS "medium", [2] AS "source", [3] AS "term", [4] AS "campaign"
FROM NAME_CTE
PIVOT 
(max(VALUE) FOR RowNum IN ([1],[2],[3],[4])) AS PVT

Pregunta hecha hace 3 años, 4 meses, 29 días - Por techtactician


4 Respuestas:

  • It # Tienes datos de JSON. Si es así, recomendaría funciones JSON en lugar de funciones de cuerda:

    select s.id, j.*
    from seodata s
    cross apply openjson(s.utmparams) with(
        medium   nvarchar(50),
        source   nvarchar(50),
        term     nvarchar(50),
        campaign nvarchar(50)
    ) j
    

    Respondida el Dec 18, 2020 a las 14:37 - por bytebuster

    Votos positivos: 0 | Votos negativos: 0

  • Como alguien más mencionó, probablemente hay mejores maneras de manejar json si eso es de hecho lo que estás haciendo. Dicho esto, aquí está mi solución simplemente usando aplicación cruzada, algunas funciones de reemplazo y pivote.

    DROP TABLE IF EXISTS #Table
    CREATE TABLE #Table
    (
    SampleData VARCHAR(MAX)
    )
    INSERT INTO #Table VALUES
    ('{\""medium\"":\""cpc\"",\""source\"":\""google\"",\""term\"":\""virtual cocktail making classes\"",\""campaign\"":\""virtual-events\""}')
    
    SELECT
    *
    FROM
    (
    SELECT
    SampleData
    ,REPLACE(LEFT(value,CHARINDEX(':',value)-1),'{','') Col
    ,REPLACE(RIGHT(value,LEN(value) - CHARINDEX(':',value)),'}','') Value
    FROM #Table
    CROSS APPLY STRING_SPLIT(REPLACE(REPLACE(SampleData,'""',''),'\',''),',')
    ) z
    PIVOT
    (
    MAX(Value)
    FOR Col IN (medium, source, term, campaign)
    ) p
    

    Respondida el Dec 18, 2020 a las 14:45 - por devguru123

    Votos positivos: 0 | Votos negativos: 0

  • El código que proporcionaste parece correcto, pero la función STRING_SPLIT() en SQL Server requiere un argumento adicional que es el carácter delimitador. En este caso, el carácter delimitador es una coma, por lo que debes usarlo de la siguiente manera:

    sql
    SELECT  id, VALUE
    , ROW_NUMBER() OVER(PARTITION by id ORDER BY id) AS "RowNum"
    INTO NAME_CTEFROM seodata
    CROSS APPLY
    string_split(utmparams,',','","')
    
    SELECT id,
    [1] AS "medium", [2] AS "source", [3] AS "term", [4] AS "campaign"
    FROM NAME_CTEPIVOT 
    (max(VALUE) FOR RowNum IN ([1],[2],[3],[4])) AS PVT
    

    Debes tener en cuenta que he usado INTO #NAME_CTE para insertar los resultados en una tabla temporal y luego he hecho referencia a esa tabla temporal en el segundo SELECT. Por favor, inténtalo de esta manera y verifica si resuelve tu problema.

    Respondida el Dec 19, 2020 a las 14:35 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • La consulta que proporcionaste tiene un error de sintaxis cerca de APPLY porque falta la palabra clave AS antes del alias de la tabla derivada común (CTE) NAME_CTE. La consulta corregida es:

    sql
    (SELECT  id, VALUE
    , ROW_NUMBER() OVER(PARTITION by id ORDER BY id) AS "RowNum"
    FROM seodata
    CROSS APPLY
    string_split(utmparams,',')
    ) AS NAME_CTE
    
    SELECT id,
    [1] AS "medium", [2] AS "source", [3] AS "term", [4] AS "campaign"
    FROM NAME_CTE
    PIVOT 
    (max(VALUE) FOR RowNum IN ([1],[2],[3],[4])) AS PVT
    

    Además, la función string_split no es una función nativa de SQL Server. Si estás utilizando SQL Server, puedes utilizar la función DelimitedSplit8K de la biblioteca de extensiones CLR para dividir cadenas por un delimitador.

    Aquí tienes un ejemplo utilizando DelimitedSplit8K:

    sql
    
    • - Instalar la biblioteca de extensiones CLR
    CREATE ASSEMBLY DelimitedSplit8K FROM 'C:\path\to\DelimitedSplit8K.dll' WITH PERMISSION_SET = UNSAFE; SELECT id, VALUE , ROW_NUMBER() OVER(PARTITION by id ORDER BY id) AS "RowNum" FROM seodata CROSS APPLY DelimitedSplit8K(utmparams, ',')

    Después de ejecutar esta consulta, puedes utilizar la CTE resultante para pivotar los datos y obtener las columnas medium, source, term y campaign.

    Respondida el Dec 19, 2020 a las 14:42 - por Gemini

    Votos positivos: 0 | Votos negativos: 0