Pregunta: como desdoblar un campo de texto que contiene una lista de enteros combinandolo con otro campo...

29/11/2006 - 14:59 por J.A. García Barceló | Informe spam
Buenas tardes grupo:

Me encuentro con una tabla, a la que despues de haberle hecho el filtro
WHERE me retorna un par de campos, el segundo de ellos, cadena de caracteres
con valores separados por comas:

A B
1 '1, 5, 9'
3 '8, 10'


Quisiera una consulta que me desdoblara esa lista de enteros y me hiciera un
cross join con el campo A para retornar algo asi como:

A C
1 1
1 5
1 9
3 8
3 10

Me he creado una función que retorna una tabla de enteros a partir de una
lista de enteros, pero no consigo ver la manera de combinar esta funcion con
lo que finalmente necesito.


CREATE FUNCTION [dbo].[SelectFromInt] (@Cadena varchar(128)) returns @Tabla
TABLE (Value int)
AS
BEGIN
DECLARE @index1 int,
@index2 int
SET @index1 = 1
SET @Cadena = ',' + RTRIM(@Cadena)
WHILE (@index1 <> 0)
BEGIN
SET @index1 = CHARINDEX(',', @Cadena)
SET @index2 = CHARINDEX(',', @Cadena, @index1+1)
IF @index2 = 0 SET @Index2 = LEN(@Cadena)+1
IF (@index1 <> 0) INSERT @tabla SELECT CAST(SUBSTRING(@Cadena, @index1+1
,@index2-@index1-1) as int)
SET @Cadena = LTRIM(SUBSTRING(@Cadena, @index2, LEN(@Cadena)))
END
RETURN
END


¿Puede alguien echarme una mano? Puede ser que la funcion cuyo código
adjunto no sea necesaria despues de todo.

Muchas gracias de antemano.

J.A. García Barceló
http://jagbarcelo.blogspot.com

Preguntas similare

Leer las respuestas

#1 Miguel egea
29/11/2006 - 22:07 | Informe spam
No me gustan las funciones para hacer estas cosas, menos los cursores.
Basado en un ejemplo del maestro Itzik ben gan te adjunto código para SQL
Server 2005, la unica cosa especial de 2005 es que uso una CTE para
conseguir los números del 1 al 1000 en una tabla, por lo demás código TSQL
normal

if not object_id('tempdb..#t') is null

drop table #t

go

select 1 a, '1, 5, 9' b into #t

union all

select 3 , '8, 10'

go

/* Cte para obtener los primeros 9000 números */

with cte as

(

select 1 id

union all

select id+1 from cte where id<1000

)

select * ,substring(b,id+1,patindex('%,%',substring(b,id+1,len(b)))-1) from
cte

inner join (select a,','+b+',' b from #t) t

on substring(t.b,id,1)=',' and len(b)>id

option(maxrecursion 0)



Saludos

Miguel Egea

"J.A. García Barceló" wrote in message
news:
Buenas tardes grupo:

Me encuentro con una tabla, a la que despues de haberle hecho el filtro
WHERE me retorna un par de campos, el segundo de ellos, cadena de
caracteres con valores separados por comas:

A B
1 '1, 5, 9'
3 '8, 10'


Quisiera una consulta que me desdoblara esa lista de enteros y me hiciera
un cross join con el campo A para retornar algo asi como:

A C
1 1
1 5
1 9
3 8
3 10

Me he creado una función que retorna una tabla de enteros a partir de una
lista de enteros, pero no consigo ver la manera de combinar esta funcion
con lo que finalmente necesito.


CREATE FUNCTION [dbo].[SelectFromInt] (@Cadena varchar(128)) returns
@Tabla TABLE (Value int)
AS
BEGIN
DECLARE @index1 int,
@index2 int
SET @index1 = 1
SET @Cadena = ',' + RTRIM(@Cadena)
WHILE (@index1 <> 0)
BEGIN
SET @index1 = CHARINDEX(',', @Cadena)
SET @index2 = CHARINDEX(',', @Cadena, @index1+1)
IF @index2 = 0 SET @Index2 = LEN(@Cadena)+1
IF (@index1 <> 0) INSERT @tabla SELECT CAST(SUBSTRING(@Cadena,
@index1+1 ,@) as int)
SET @Cadena = LTRIM(SUBSTRING(@Cadena, @index2, LEN(@Cadena)))
END
RETURN
END


¿Puede alguien echarme una mano? Puede ser que la funcion cuyo código
adjunto no sea necesaria despues de todo.

Muchas gracias de antemano.

J.A. García Barceló
http://jagbarcelo.blogspot.com


Respuesta Responder a este mensaje
#2 J.A. García Barceló
30/11/2006 - 10:25 | Informe spam
Muchisimas gracias. Creo que no se me hubiera ocurrido una solución tan
lineal (tsql) ni en un millón de años. ¿De que fuentes hay que beber para
obtener esos conocimientos? jeje

Con tu permiso, daré de alta una entrada en mi blog con esta informacion,
por supuesto citando las fuentes ;)

Un saludo.

J.A. García Barceló
http://jagbarcelo.blogspot.com

"Miguel egea" escribió en el mensaje
news:OPPolp$
No me gustan las funciones para hacer estas cosas, menos los cursores.
Basado en un ejemplo del maestro Itzik ben gan te adjunto código para SQL
Server 2005, la unica cosa especial de 2005 es que uso una CTE para
conseguir los números del 1 al 1000 en una tabla, por lo demás código TSQL
normal

if not object_id('tempdb..#t') is null

drop table #t

go

select 1 a, '1, 5, 9' b into #t

union all

select 3 , '8, 10'

go

/* Cte para obtener los primeros 9000 números */

with cte as

(

select 1 id

union all

select id+1 from cte where id<1000

)

select * ,substring(b,id+1,patindex('%,%',substring(b,id+1,len(b)))-1)
from cte

inner join (select a,','+b+',' b from #t) t

on substring(t.b,id,1)=',' and len(b)>id

option(maxrecursion 0)



Saludos

Miguel Egea

"J.A. García Barceló" wrote in message
news:
Buenas tardes grupo:

Me encuentro con una tabla, a la que despues de haberle hecho el filtro
WHERE me retorna un par de campos, el segundo de ellos, cadena de
caracteres con valores separados por comas:

A B
1 '1, 5, 9'
3 '8, 10'


Quisiera una consulta que me desdoblara esa lista de enteros y me hiciera
un cross join con el campo A para retornar algo asi como:

A C
1 1
1 5
1 9
3 8
3 10

Me he creado una función que retorna una tabla de enteros a partir de una
lista de enteros, pero no consigo ver la manera de combinar esta funcion
con lo que finalmente necesito.


CREATE FUNCTION [dbo].[SelectFromInt] (@Cadena varchar(128)) returns
@Tabla TABLE (Value int)
AS
BEGIN
DECLARE @index1 int,
@index2 int
SET @index1 = 1
SET @Cadena = ',' + RTRIM(@Cadena)
WHILE (@index1 <> 0)
BEGIN
SET @index1 = CHARINDEX(',', @Cadena)
SET @index2 = CHARINDEX(',', @Cadena, @index1+1)
IF @index2 = 0 SET @Index2 = LEN(@Cadena)+1
IF (@index1 <> 0) INSERT @tabla SELECT CAST(SUBSTRING(@Cadena,
@index1+1 ,@) as int)
SET @Cadena = LTRIM(SUBSTRING(@Cadena, @index2, LEN(@Cadena)))
END
RETURN
END


¿Puede alguien echarme una mano? Puede ser que la funcion cuyo código
adjunto no sea necesaria despues de todo.

Muchas gracias de antemano.

J.A. García Barceló
http://jagbarcelo.blogspot.com






Respuesta Responder a este mensaje
#3 Miguel egea
30/11/2006 - 11:03 | Informe spam
por supuesto!!, yo lo publicaré en portalsql, para que pueda ser leido por
más gente. :)
"J.A. García Barceló" wrote in message
news:
Muchisimas gracias. Creo que no se me hubiera ocurrido una solución tan
lineal (tsql) ni en un millón de años. ¿De que fuentes hay que beber para
obtener esos conocimientos? jeje

Con tu permiso, daré de alta una entrada en mi blog con esta informacion,
por supuesto citando las fuentes ;)

Un saludo.

J.A. García Barceló
http://jagbarcelo.blogspot.com

"Miguel egea" escribió en el mensaje
news:OPPolp$
No me gustan las funciones para hacer estas cosas, menos los cursores.
Basado en un ejemplo del maestro Itzik ben gan te adjunto código para SQL
Server 2005, la unica cosa especial de 2005 es que uso una CTE para
conseguir los números del 1 al 1000 en una tabla, por lo demás código
TSQL normal

if not object_id('tempdb..#t') is null

drop table #t

go

select 1 a, '1, 5, 9' b into #t

union all

select 3 , '8, 10'

go

/* Cte para obtener los primeros 9000 números */

with cte as

(

select 1 id

union all

select id+1 from cte where id<1000

)

select * ,substring(b,id+1,patindex('%,%',substring(b,id+1,len(b)))-1)
from cte

inner join (select a,','+b+',' b from #t) t

on substring(t.b,id,1)=',' and len(b)>id

option(maxrecursion 0)



Saludos

Miguel Egea

"J.A. García Barceló" wrote in message
news:
Buenas tardes grupo:

Me encuentro con una tabla, a la que despues de haberle hecho el filtro
WHERE me retorna un par de campos, el segundo de ellos, cadena de
caracteres con valores separados por comas:

A B
1 '1, 5, 9'
3 '8, 10'


Quisiera una consulta que me desdoblara esa lista de enteros y me
hiciera un cross join con el campo A para retornar algo asi como:

A C
1 1
1 5
1 9
3 8
3 10

Me he creado una función que retorna una tabla de enteros a partir de
una lista de enteros, pero no consigo ver la manera de combinar esta
funcion con lo que finalmente necesito.


CREATE FUNCTION [dbo].[SelectFromInt] (@Cadena varchar(128)) returns
@Tabla TABLE (Value int)
AS
BEGIN
DECLARE @index1 int,
@index2 int
SET @index1 = 1
SET @Cadena = ',' + RTRIM(@Cadena)
WHILE (@index1 <> 0)
BEGIN
SET @index1 = CHARINDEX(',', @Cadena)
SET @index2 = CHARINDEX(',', @Cadena, @index1+1)
IF @index2 = 0 SET @Index2 = LEN(@Cadena)+1
IF (@index1 <> 0) INSERT @tabla SELECT CAST(SUBSTRING(@Cadena,
@index1+1 ,@) as int)
SET @Cadena = LTRIM(SUBSTRING(@Cadena, @index2, LEN(@Cadena)))
END
RETURN
END


¿Puede alguien echarme una mano? Puede ser que la funcion cuyo código
adjunto no sea necesaria despues de todo.

Muchas gracias de antemano.

J.A. García Barceló
http://jagbarcelo.blogspot.com










email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida