Saltar al contenido principal

 none
Obtengo cadenas de resultados repetidos intentando utilizar función split RRS feed

  • Pregunta

  • Hola,
    Estoy intentado obtener una relación de documentos cancelados, esta consulta:

    SELECT d.cseriedocumento + CAST(d.cFolio AS VARCHAR) AS [Factura],
         CAST(d.cfecha AS DATE) [Fecha Factura], 
         f.cuuid [UUID], 
         f.ccadpedi [UUID Relacionado], 
         do.cfolio [Factura_CANCELADA],
         CAST(do.cfecha AS DATE) AS [Fecha factura CANCELADA],
         CAST(g.cfechacanc AS DATE) AS [Fecha Cancelación]
    FROM admFoliosDigitales f
         LEFT JOIN admFoliosDigitales g ON CAST(f.ccadpedi AS VARCHAR(500)) = g.cuuid
         INNER JOIN admDocumentos d ON d.ciddocumento = f.ciddocto
         LEFT JOIN admDocumentos do ON do.ciddocumento = g.ciddocto     
         CROSS APPLY 
         Splitjp(f.ccadpedi, '|')
    WHERE d.ciddocumentode = 4
    AND d.cfecha BETWEEN '20191001' AND '20191109'								

    me devuelve estos resultados:


    Se observa que para el folio 157667, es correcto que devuelva 6 filas, pero yo esperaría que el contenido de la columna UUID Relacionado tuviera cada identificador de cada documento y esto no está funcionando, yo requiero obtener algo así:

    Agradezco si tienen alguna recomendación para resolver este problema:

    Esta es la función split que encontré por la red, ya que estoy utilizando Sql 2014
    CREATE FUNCTION [dbo].[Splitjp] (@String nvarchar (4000), @Delimitador nvarchar (10)) 
                    returns @ValueTable table ([Value] nvarchar(4000))
    begin
     declare @NextString nvarchar(4000)
     declare @Pos int
     declare @NextPos int
     declare @CommaCheck nvarchar(1)
     
     --Inicializa
     set @NextString = ''
     set @CommaCheck = right(@String,1) 
     
     set @String = @String + @Delimitador
     
     --Busca la posición del primer delimitador
     set @Pos = charindex(@Delimitador,@String)
     set @NextPos = 1
     
     --Itera mientras exista un delimitador en el string
     while (@pos <> 0)  
     begin
      set @NextString = substring(@String,1,@Pos - 1)
     
      insert into @ValueTable ( [Value]) Values (@NextString)
     
      set @String = substring(@String,@pos +1,len(@String))
      
      set @NextPos = @Pos
      set @pos  = charindex(@Delimitador,@String)
     end
     
     return
    end
    Saludos,
    Javier
    • Editado jparada jueves, 14 de noviembre de 2019 19:50
    jueves, 14 de noviembre de 2019 19:50

Respuestas

  • Pero no entiendo por qué no estoy obteniendo los datos que corresponden a cada identificador, es decir, yo esperaría obtener estos datos... qué me está faltando?.

    Prueba

    -- código #1 v2
    SELECT d.cseriedocumento + CAST(d.cFolio AS VARCHAR) as Factura,
         cast (d.cfecha as date) as [Fecha Factura], 
         f.cuuid as UUID, 
         SS.[value] as [UUID Relacionado], 
         do.cfolio as [Factura_CANCELADA],
         cast (do.cfecha as date) as [Fecha factura CANCELADA],
         cast (g.cfechacanc as date) as [Fecha Cancelación]
         
    FROM admFoliosDigitales f
         INNER JOIN admDocumentos d ON d.ciddocumento = f.ciddocto
    CROSS APPLY Splitjp(f.ccadpedi, '|') as SS LEFT JOIN admFoliosDigitales g ON g.cuuid = SS.[value] LEFT JOIN admDocumentos do ON do.ciddocumento = g.ciddocto WHERE d.ciddocumentode = 4 AND d.cfecha BETWEEN '20191001' AND '20191109';



    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Propuesto como respuesta Pablo RubioModerator viernes, 15 de noviembre de 2019 23:46
    • Editado José Diz sábado, 16 de noviembre de 2019 10:11
    • Marcado como respuesta jparada sábado, 16 de noviembre de 2019 15:48
    viernes, 15 de noviembre de 2019 23:10

Todas las respuestas

  • Hola jparada:

    Función delimitedSplit8k

    /* created by jeff Moden */
    
    ALTER FUNCTION [dbo].[DelimitedSplit8K]
    (@pString    VARCHAR(8000), 
     @pDelimiter CHAR(1)
    )
    RETURNS TABLE
    WITH SCHEMABINDING
    AS
         RETURN
         WITH E1(N)
              AS (SELECT 1
                  UNION ALL
                  SELECT 1
                  UNION ALL
                  SELECT 1
                  UNION ALL
                  SELECT 1
                  UNION ALL
                  SELECT 1
                  UNION ALL
                  SELECT 1
                  UNION ALL
                  SELECT 1
                  UNION ALL
                  SELECT 1
                  UNION ALL
                  SELECT 1
                  UNION ALL
                  SELECT 1), --10E+1 or 10 rows
              E2(N)
              AS (SELECT 1
                  FROM E1 a, 
                       E1 b), --10E+2 or 100 rows
              E4(N)
              AS (SELECT 1
                  FROM E2 a, 
                       E2 b), --10E+4 or 10,000 rows max
              cteTally(N)
              AS (SELECT TOP (ISNULL(DATALENGTH(@pString), 0)) ROW_NUMBER() OVER(
                                                               ORDER BY
                  (
                      SELECT NULL
                  ))
                  FROM E4),
              cteStart(N1)
              AS (SELECT 1
                  UNION ALL
                  SELECT t.N + 1
                  FROM cteTally t
                  WHERE SUBSTRING(@pString, t.N, 1) = @pDelimiter),
              cteLen(N1, 
                     L1)
              AS (SELECT s.N1, 
                         ISNULL(NULLIF(CHARINDEX(@pDelimiter, @pString, s.N1), 0) - s.N1, 8000)
                  FROM cteStart s)
              SELECT ItemNumber = ROW_NUMBER() OVER(
                     ORDER BY L.N1), 
                     Item = SUBSTRING(@pString, L.N1, L.L1)
              FROM cteLen L;

    https://www.sqlservercentral.com/articles/tally-oh-an-improved-sql-8k-%E2%80%9Ccsv-splitter%E2%80%9D-function

    jueves, 14 de noviembre de 2019 20:37
  • Hola Javi,
    Gracias por tu respuesta, pero utilizando esta función que me indicas, obtengo exactamente los mismos resultados expuestos.

    Alguna otra idea?.

    Saludos,
    Javier
    • Editado jparada jueves, 14 de noviembre de 2019 20:55
    jueves, 14 de noviembre de 2019 20:54
  • Prueba

    -- código #1
    SELECT d.cseriedocumento + CAST(d.cFolio AS VARCHAR) as Factura,
         cast (d.cfecha as date) as [Fecha Factura], 
         f.cuuid as UUID, 
         SS.[value] as [UUID Relacionado], 
         do.cfolio as [Factura_CANCELADA],
         cast (do.cfecha as date) as [Fecha factura CANCELADA],
         cast (g.cfechacanc as date) as [Fecha Cancelación]
         
    FROM admFoliosDigitales f
         LEFT JOIN admFoliosDigitales g ON CAST(f.ccadpedi AS VARCHAR(500)) = g.cuuid
         INNER JOIN admDocumentos d ON d.ciddocumento = f.ciddocto
         LEFT JOIN admDocumentos do ON do.ciddocumento = g.ciddocto     
         CROSS APPLY Splitjp(f.ccadpedi, '|') as SS
    
    WHERE d.ciddocumentode = 4
         AND d.cfecha BETWEEN '20191001' AND '20191109';




    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    jueves, 14 de noviembre de 2019 21:26
  • Hola José,
    Gracias por responder, esto funcionó como se espera, adjunto la imagen con los resultados:

    Pero no entiendo por qué no estoy obteniendo los datos que corresponden a cada identificador, es decir, yo esperaría obtener estos datos... qué me está faltando?.


    Agradezco su tiempo y ayuda.

    Saludos,
    Javier

    • Editado jparada viernes, 15 de noviembre de 2019 19:31
    viernes, 15 de noviembre de 2019 19:31
  • Pero no entiendo por qué no estoy obteniendo los datos que corresponden a cada identificador, es decir, yo esperaría obtener estos datos... qué me está faltando?.

    Prueba

    -- código #1 v2
    SELECT d.cseriedocumento + CAST(d.cFolio AS VARCHAR) as Factura,
         cast (d.cfecha as date) as [Fecha Factura], 
         f.cuuid as UUID, 
         SS.[value] as [UUID Relacionado], 
         do.cfolio as [Factura_CANCELADA],
         cast (do.cfecha as date) as [Fecha factura CANCELADA],
         cast (g.cfechacanc as date) as [Fecha Cancelación]
         
    FROM admFoliosDigitales f
         INNER JOIN admDocumentos d ON d.ciddocumento = f.ciddocto
    CROSS APPLY Splitjp(f.ccadpedi, '|') as SS LEFT JOIN admFoliosDigitales g ON g.cuuid = SS.[value] LEFT JOIN admDocumentos do ON do.ciddocumento = g.ciddocto WHERE d.ciddocumentode = 4 AND d.cfecha BETWEEN '20191001' AND '20191109';



    José Diz     Belo Horizonte, MG - Brasil     [query performance tuning: Porto SQL]


    Este conteúdo é fornecido sem garantias de qualquer tipo, seja expressa ou implícita.

    • Propuesto como respuesta Pablo RubioModerator viernes, 15 de noviembre de 2019 23:46
    • Editado José Diz sábado, 16 de noviembre de 2019 10:11
    • Marcado como respuesta jparada sábado, 16 de noviembre de 2019 15:48
    viernes, 15 de noviembre de 2019 23:10
  • Hola José,
    funciona perfecto, Gracias por tu ayuda.

    Saludos,
    Javier
    • Editado jparada sábado, 16 de noviembre de 2019 15:48
    sábado, 16 de noviembre de 2019 15:48