none
Dividir campo con números de teléfono RRS feed

  • Pregunta

  • Buenas noches amigos, espero que estén bien, quisiera saber como puedo dividir un campo que contiene unos numeros de telefono en varios campos ya que debo decir cuales son movil1, movil2, movil3.... fijo1, fijo2 y así, el campo que contiene los telefonos esta de la siguiente forma: 

    Telefonos 

    033204789957

    033185222438-033175515033

    033017627378-033016455955-033223253632

    033114842729-033057690178-033132382085-033202472757-033156175501

    0563935125-0584882230-033163935125-033184882230

    Como pueden observar el tamaño de la cadena puede variar dependiendo del numero de teléfonos que haya a veces puede haber 3 o hasta 5 teléfonos o solo en 1 también, y el orden también varía o sea puede estar primero un numero móvil y luego un teléfono fijo o al contrario, hasta el momento lo que he conseguido hacer es lo siguiente: 

    SUBSTRING(a.telefonos,1, case when CHARINDEX('-',a.telefonos,1) =0 then len(a.telefonos) else CHARINDEX('-',a.telefonos,1)-1 END)   

    lo cual me permitió apenas sacar el primer número  y quedo así: 

    033204789957

    033185222438

    033017627378

    033114842729

    0563935125

    Pero no se como sacar los demás me confundo en el hecho de que la cadena varia el tamaño y no se como podría validar eso para que vayan quedando en columnas diferentes que es lo que necesito. Agradezco su ayuda y colaboración, que estén bien amigos.   


     


    lunes, 3 de septiembre de 2018 23:53

Respuestas

  • Hola Fredo2094:

    Te dejo un script para realizar lo que solicitas.

    DECLARE @telefonos NVARCHAR(100);
    SET @telefonos = '033114842729-033057690178-033132382085-033202472757-033156175501';
    SET @telefonos = REPLACE(@telefonos, '-', ',');
    
    
    -- convertimos en un conjunto de valores
    -- truco hacer join donde la posicion de la coma coincida con un valor
    -- necesitamos valores de 1 a la longitud de la cadena
    
    WITH nums
         AS (
         SELECT 1 num
         UNION ALL
         SELECT num + 1
         FROM nums
         WHERE num < 100)
         SELECT SUBSTRING(p, num+1, PATINDEX('%,%', SUBSTRING(p, num+1, 100)+',')-1)
         FROM nums
              INNER JOIN
    (
        SELECT ','+@telefonos p
    ) p ON SUBSTRING(p, num, 1) = ',';
    
    Espero te ayude

    Un saludo

    • Propuesto como respuesta osrol martes, 4 de septiembre de 2018 13:15
    • Marcado como respuesta Pablo RubioModerator jueves, 6 de septiembre de 2018 7:54
    martes, 4 de septiembre de 2018 6:39
  • Cual version de SQL Server usas?

    Desde la version 2016 contamos con la funcion STRING_SPLIT la cual devuelve una tabla con una columna conteniendo cada miembro de la lista.

    select *
    from T outer apply STRING_SPLIT(T.telefonos, '-') as S;

    Si tienes una version anterior entonces te recomendaria que crees una funcion tipo tabla en linea para que puedas usarla cada vez que la necesites sin necesidad de duplicar el codigo / logica para desmantelar la lista.

    Ejemplo:

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    -- Itzik's VATN
    CREATE FUNCTION [dbo].[ufn_GetNums](@low AS bigint, @high AS bigint) 
    RETURNS table
    AS
    RETURN (
    WITH
    L0 AS (SELECT c FROM (VALUES(1),(1)) AS D(c)),
    L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B),
    L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B),
    L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B),
    L4 AS (SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B),
    L5 AS (SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B),
    Nums AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum FROM L5)
    SELECT TOP(@high - @low + 1) @low + rownum - 1 AS n
    FROM Nums
    ORDER BY rownum
    );
    
    GO
    -- Erland's split_me
    CREATE FUNCTION [dbo].[ufn_inline_split_me](@param nvarchar(MAX), @delimiter nchar(1) = N',')
    RETURNS table AS
    RETURN (
    SELECT
        ROW_NUMBER() OVER(ORDER BY n) AS pos,
        LTRIM(RTRIM(CONVERT(nvarchar(4000),
            SUBSTRING(@param, n,
                CHARINDEX(@delimiter COLLATE Slovenian_BIN2, @param + CONVERT(nvarchar(MAX), @delimiter), n) - n)))) AS Value
    FROM
        dbo.ufn_GetNums(1, LEN(@param))
    WHERE
        SUBSTRING(CONVERT(nvarchar(MAX), @delimiter) + @param, n, 1) = @delimiter COLLATE Slovenian_BIN2
    );
    GO
    DECLARE @T table(
    col1 varchar(512)
    );
    
    INSERT INTO @T (
        col1
    	)
    VALUES
    	('033204789957'),
    	('033185222438-033175515033'),
    	('033017627378-033016455955-033223253632'),
    	('033114842729-033057690178-033132382085-033202472757-033156175501'),
    	('0563935125-0584882230-033163935125-033184882230');
    
    SELECT
    	*
    FROM
    	@T AS T
    	OUTER APPLY
    	dbo.ufn_inline_split_me(T.col1, N'-') AS S;
    GO


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    martes, 4 de septiembre de 2018 12:28

Todas las respuestas

  • Hola Fredo2094:

    Te dejo un script para realizar lo que solicitas.

    DECLARE @telefonos NVARCHAR(100);
    SET @telefonos = '033114842729-033057690178-033132382085-033202472757-033156175501';
    SET @telefonos = REPLACE(@telefonos, '-', ',');
    
    
    -- convertimos en un conjunto de valores
    -- truco hacer join donde la posicion de la coma coincida con un valor
    -- necesitamos valores de 1 a la longitud de la cadena
    
    WITH nums
         AS (
         SELECT 1 num
         UNION ALL
         SELECT num + 1
         FROM nums
         WHERE num < 100)
         SELECT SUBSTRING(p, num+1, PATINDEX('%,%', SUBSTRING(p, num+1, 100)+',')-1)
         FROM nums
              INNER JOIN
    (
        SELECT ','+@telefonos p
    ) p ON SUBSTRING(p, num, 1) = ',';
    
    Espero te ayude

    Un saludo

    • Propuesto como respuesta osrol martes, 4 de septiembre de 2018 13:15
    • Marcado como respuesta Pablo RubioModerator jueves, 6 de septiembre de 2018 7:54
    martes, 4 de septiembre de 2018 6:39
  • Cual version de SQL Server usas?

    Desde la version 2016 contamos con la funcion STRING_SPLIT la cual devuelve una tabla con una columna conteniendo cada miembro de la lista.

    select *
    from T outer apply STRING_SPLIT(T.telefonos, '-') as S;

    Si tienes una version anterior entonces te recomendaria que crees una funcion tipo tabla en linea para que puedas usarla cada vez que la necesites sin necesidad de duplicar el codigo / logica para desmantelar la lista.

    Ejemplo:

    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    -- Itzik's VATN
    CREATE FUNCTION [dbo].[ufn_GetNums](@low AS bigint, @high AS bigint) 
    RETURNS table
    AS
    RETURN (
    WITH
    L0 AS (SELECT c FROM (VALUES(1),(1)) AS D(c)),
    L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B),
    L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B),
    L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B),
    L4 AS (SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B),
    L5 AS (SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B),
    Nums AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum FROM L5)
    SELECT TOP(@high - @low + 1) @low + rownum - 1 AS n
    FROM Nums
    ORDER BY rownum
    );
    
    GO
    -- Erland's split_me
    CREATE FUNCTION [dbo].[ufn_inline_split_me](@param nvarchar(MAX), @delimiter nchar(1) = N',')
    RETURNS table AS
    RETURN (
    SELECT
        ROW_NUMBER() OVER(ORDER BY n) AS pos,
        LTRIM(RTRIM(CONVERT(nvarchar(4000),
            SUBSTRING(@param, n,
                CHARINDEX(@delimiter COLLATE Slovenian_BIN2, @param + CONVERT(nvarchar(MAX), @delimiter), n) - n)))) AS Value
    FROM
        dbo.ufn_GetNums(1, LEN(@param))
    WHERE
        SUBSTRING(CONVERT(nvarchar(MAX), @delimiter) + @param, n, 1) = @delimiter COLLATE Slovenian_BIN2
    );
    GO
    DECLARE @T table(
    col1 varchar(512)
    );
    
    INSERT INTO @T (
        col1
    	)
    VALUES
    	('033204789957'),
    	('033185222438-033175515033'),
    	('033017627378-033016455955-033223253632'),
    	('033114842729-033057690178-033132382085-033202472757-033156175501'),
    	('0563935125-0584882230-033163935125-033184882230');
    
    SELECT
    	*
    FROM
    	@T AS T
    	OUTER APPLY
    	dbo.ufn_inline_split_me(T.col1, N'-') AS S;
    GO


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    martes, 4 de septiembre de 2018 12:28