desde hasta

02/05/2006 - 19:19 por claudio alabarce | Informe spam
Hola,

Tengo una consulta,
Tengo la siguiente tabla:

Numeros
940
941
942
943
8000
19075
19076
19077

y quiero devolver un string de la siguiente forma:
940 al 943 - 8000 - 19075 al 19077.

Se puede hacer un SP o Funcion que me devuelva este resultado sin utilizar
cursores?

Muchas gracias.

Script:
if exists (select * from dbo.sysobjects where id =
object_id(N'[dbo].[Table1]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[Table1]
GO
CREATE TABLE [dbo].[Table1] (
[Numeros] [int] NOT NULL
) ON [PRIMARY]
GO

Insert table1 (Numeros) values(940)
Insert table1 (Numeros) values(941)
Insert table1 (Numeros) values(942)
Insert table1 (Numeros) values(943)
Insert table1 (Numeros) values(8000)
Insert table1 (Numeros) values(19075)
Insert table1 (Numeros) values(19076)
Insert table1 (Numeros) values(19077)

Preguntas similare

Leer las respuestas

#6 Miguel Egea
02/05/2006 - 23:40 | Informe spam
Hola Claudio, no me siento especialmente orgulloso de este query, creo que
puede hacerse más eficientemente, pero bueno, es un pelín tarde y prefiero
ver house (es una serie cojonuda que están poniendo en un canal español y
que seguro que conoces), el caso es que igual con este te ayuda.
Hay algunos cmapos que no uso, orden2, puedes quitarlos y falta añadir el
orden adecuado, pero eso es más sencillo creo :-)

Saludillos
select 'Desde el ' + cast(min(b.orden) as varchar(100)) + ' hasta el ' +
cast(max(a.numeros) as varchar(100))

from (

Select numeros,

(select min(Numeros) from TAble1 t where t.Numeros>Table1.Numeros) -

(select count(Numeros) from TAble1 t where t.Numeros<=Table1.Numeros) orden,

(select min(Numeros) from TAble1 t where t.Numeros>Table1.Numeros) -NUMEROS
Distancia,

(select count(Numeros) from TAble1 t where t.Numeros<=Table1.Numeros) orden2

from Table1

) a

inner join

( Select numeros,

(select min(Numeros) from TAble1 t where t.Numeros>Table1.Numeros) -

(select count(Numeros) from TAble1 t where t.Numeros<=Table1.Numeros) orden,

(select min(Numeros) from TAble1 t where t.Numeros>Table1.Numeros) -NUMEROS
Distancia,

(select count(Numeros) from TAble1 t where t.Numeros<=Table1.Numeros) orden2

from Table1

) b

on a.orden2=b.orden2+1

group by b.orden

having count(*)>1

union all

select cast(max(a.numeros) as varchar(100)) +','

from (

Select numeros,

(select min(Numeros) from TAble1 t where t.Numeros>Table1.Numeros) -

(select count(Numeros) from TAble1 t where t.Numeros<=Table1.Numeros) orden,

(select min(Numeros) from TAble1 t where t.Numeros>Table1.Numeros) -NUMEROS
Distancia,

(select count(Numeros) from TAble1 t where t.Numeros<=Table1.Numeros) orden2

from Table1

) a

inner join

( Select numeros,

(select min(Numeros) from TAble1 t where t.Numeros>Table1.Numeros) -

(select count(Numeros) from TAble1 t where t.Numeros<=Table1.Numeros) orden,

(select min(Numeros) from TAble1 t where t.Numeros>Table1.Numeros) -NUMEROS
Distancia,

(select count(Numeros) from TAble1 t where t.Numeros<=Table1.Numeros) orden2

from Table1

) b

on a.orden2=b.orden2+1

group by b.orden

having count(*)=1



Saludos

"claudio alabarce" escribió en
el mensaje news:
Miguel,

estuve probando lo que me mandaste y si tengo los siguientes numeros no
funciona, puesto que el ejemplo que me mandaste divide en 1000, no se me
ocurre como hacerlo.

1151
1161
1162
1163
1164
1165
1169
1170
1174
1175
1176
1184
1185
1187
1188
1189

El resultado deberia ser

1151
1161 al 1176
1184 al 1189

Por si no quedo claro, si un numero no tiene consecutivo o un numero
anterior va solo, y sino el primero de la serie consecutiva hasta que
termina.

Si no me explico me avisas y lo expreso nuevamente.

Gracias.



"Miguel Egea" escribió:

Por si no era eso exactamente aquí tienes algo más

declare @v varchar(max)

select @v =''

select @v=@v+(case when inicio=fin then cast(inicio as varchar(100)) +','

else cast (inicio as varchar(100)) + ' al ' + cast(fin as varchar(100))
+','

End )

from (

select min(numeros) inicio, max(numeros) fin

From table1

group by Numeros/1000

) a

select @v



Saludos

"Miguel Egea" escribió en el mensaje
news:%
> Claudio!!! dios mio cuanto tiempo sin saber de tí, que placer volver a
> leerte.
>
> Con esta consulta en 2005 tienes una aproximación interesante, pero no
> resuelve lo que quieres.
> select numeros, Rank() over (partition by Numeros/1000 order by
> numeros)
> a,Numeros/1000
>
> From table1
>
> Con esta sintaxis, más sencilla y válida para todas las versiones
> obtienes
> casi lo que quieres
>
> select min(numeros), max(numeros)
>
> From table1
>
> group by Numeros/1000
>
> y con esta otra, justo lo que quieres
>
> select case when inicio=fin then cast(inicio as varchar(100))
>
> else cast (inicio as varchar(100)) + ' al ' + cast(fin as varchar(100))
>
> End Rango
>
> from (
>
> select min(numeros) inicio, max(numeros) fin
>
> From table1
>
> group by Numeros/1000
>
> ) a
>
>
>
>
>
>
> Al principio no te entendí bien, y creí que hablabas de formar parejas,
> como no puedo resistirme pego el código aquí abajo.
>
> select a.numeros,b.numeros from
>
> (
>
> select numeros, (row_number() over( order by numeros))+1 fila from
> Table1
>
> ) a
>
> inner join
>
> (
>
> select numeros, (row_number() over( order by numeros)) fila from Table1
>
> ) b
>
> on a.fila=b.fila
>
> where a.fila%2=0
>
> go
>
>
> select numeros,
>
> (Select min(Numeros) From Table1 t where t.Numeros>table1.numeros)
> Intervalo
>
> from Table1
>
> where
>
> (Select count(Numeros) From Table1 t where
> t.Numeros<=table1.numeros)%2=1
>
>
>
>
>
>
> "claudio alabarce" <claudio
> escribió
> en el mensaje
> news:
>> Hola,
>>
>> Tengo una consulta,
>> Tengo la siguiente tabla:
>>
>> Numeros
>> 940
>> 941
>> 942
>> 943
>> 8000
>> 19075
>> 19076
>> 19077
>>
>> y quiero devolver un string de la siguiente forma:
>> 940 al 943 - 8000 - 19075 al 19077.
>>
>> Se puede hacer un SP o Funcion que me devuelva este resultado sin
>> utilizar
>> cursores?
>>
>> Muchas gracias.
>>
>> Script:
>> if exists (select * from dbo.sysobjects where id >> >> object_id(N'[dbo].[Table1]') and OBJECTPROPERTY(id, N'IsUserTable') =
>> 1)
>> drop table [dbo].[Table1]
>> GO
>> CREATE TABLE [dbo].[Table1] (
>> [Numeros] [int] NOT NULL
>> ) ON [PRIMARY]
>> GO
>>
>> Insert table1 (Numeros) values(940)
>> Insert table1 (Numeros) values(941)
>> Insert table1 (Numeros) values(942)
>> Insert table1 (Numeros) values(943)
>> Insert table1 (Numeros) values(8000)
>> Insert table1 (Numeros) values(19075)
>> Insert table1 (Numeros) values(19076)
>> Insert table1 (Numeros) values(19077)
>>
>>
>>
>
>



Respuesta Responder a este mensaje
#7 Alejandro Mesa
03/05/2006 - 15:04 | Informe spam
Claudio,

Creo que seria mejor hacer esta concatenacion en la aplicacion cliente y no
en sql server. En la version 2000 tenemos el inconveniente de que la cadena
de caracteres puede contener como maximo 8000 caracteres. De todas maneras
participo en el reto.

use northwind
go

if exists (select * from dbo.sysobjects where id =
object_id(N'[dbo].[Table1]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[Table1]
GO

CREATE TABLE [dbo].[Table1] (
[Numeros] [int] NOT NULL
) ON [PRIMARY]
GO

set nocount on

Insert table1 (Numeros) values(940)
Insert table1 (Numeros) values(941)
Insert table1 (Numeros) values(942)
Insert table1 (Numeros) values(943)
Insert table1 (Numeros) values(8000)
Insert table1 (Numeros) values(19075)
Insert table1 (Numeros) values(19076)
Insert table1 (Numeros) values(19077)

set nocount off
go

create view v1
as
select a.numeros as a_numeros, b.numeros as b_numeros
from table1 as a left join table1 as b
on not exists (
select *
from table1 as c
where c.numeros = a.numeros - 1
)
and b.numeros > a.numeros
and not exists (
select *
from table1 as c
where c.numeros >= a.numeros and c.numeros <= b.numeros
and ((select min(d.numeros) from table1 as d where d.numeros > c.numeros and
d.numeros <= b.numeros) - c.numeros) > 1
)
go

declare @s varchar(8000)

set @s = ''

select
@s = @s + case when @s = '' then '' else ' - ' end + ltrim(a_numeros) +
case when max(b_numeros) is null then '' else ' al ' end +
isnull(ltrim(max(b_numeros)), '')
from
v1 as t1
where
not exists (
select * from v1 as t2 where t2.b_numeros = t1.a_numeros
)
group by
a_numeros
order by
a_numeros

print @s
go

drop view v1
go

if exists (select * from dbo.sysobjects where id =
object_id(N'[dbo].[Table1]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[Table1]
GO


AMB

"claudio alabarce" wrote:

Hola,

Tengo una consulta,
Tengo la siguiente tabla:

Numeros
940
941
942
943
8000
19075
19076
19077

y quiero devolver un string de la siguiente forma:
940 al 943 - 8000 - 19075 al 19077.

Se puede hacer un SP o Funcion que me devuelva este resultado sin utilizar
cursores?

Muchas gracias.

Script:
if exists (select * from dbo.sysobjects where id =
object_id(N'[dbo].[Table1]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[Table1]
GO
CREATE TABLE [dbo].[Table1] (
[Numeros] [int] NOT NULL
) ON [PRIMARY]
GO

Insert table1 (Numeros) values(940)
Insert table1 (Numeros) values(941)
Insert table1 (Numeros) values(942)
Insert table1 (Numeros) values(943)
Insert table1 (Numeros) values(8000)
Insert table1 (Numeros) values(19075)
Insert table1 (Numeros) values(19076)
Insert table1 (Numeros) values(19077)



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