Fechas Sobrepuestas

25/02/2005 - 01:31 por Pablo Guevara | Informe spam
Necesito hacer una consulta con registros que tienen una fecha inicial y
fecha final. Me piden que no se pueda ingresar una fecha que ya este
incluida en el periodo, poer ejemplo:

Enero 01/2005 - Diciembre 31/2005

Si intentamos ingresar :

Julio 01/2005 Julio 21/2006

el sistema confirma que la fecha se sobrepone a una ya existente.

¿Alguna idea?

Thx

Pablo

+++

Preguntas similare

Leer las respuestas

#1 Jorge Bustos
25/02/2005 - 02:14 | Informe spam
create table t (i datetime, f datetime)
insert into t values ('20050101','20050131')


insertar y uno concreto que estés vigilando en la tabla:
1)
i--f
@
por ejemplo del 15 de enero al 15 de febrero

2)
i--f
@
por ejemplo del 31 de diciembre anterior al 15 de enero

3)
i--f
@
por ejemplo del 10 al 20 de enero

4)
i--f
@
por ejemplo del 1 de diciembre anterior al 1 de febrero

Para localizar estos posibles casos de intersección hay que realizar estas
consultas:
(OJO: pseudocódigo para entender mejor la exlicación. el código final va en
el procedimiento)
1) select * from t where t.i<=@ni<=t.f
2) select * from t where t.i<=@nf<=t.f
3) cualquiera de las comprobaciones 1) y 2) reconocen esta intersección
4) serían dos consultas:
select * from t where @ni<=t.i<=@nf
select * from t where @ni<=t.f<=@nf
Pero con comprobar que o bien i o bien f estén dentro de el rango entre ni y
nf basta para saber que se solapan

En resumen, para comprobar si un rango está ocupado basta con:

create procedure disponible
@ni datetime, @nf datetime
as
begin
select count(*) from t
where
(t.i<=@ni and @ni<=t.f)
or
(t.i<=@nf and @nf<=t.f)
or
(@ni<=t.i and t.i<=@nf)
end

Si la cuenta devuelta es mayor que cero el periodo está ocupado.

Puedes comprobar los 6 casos posibles (4 intersecciones de arriba, y dos que
no tienen intersección)
exec disponible '20050115','20050215'
exec disponible '20041231','20050115'
exec disponible '20050110','20050120'
exec disponible '20041201','20050201'
exec disponible '20041201','20041215'
exec disponible '20051201','20051215'

Ahora solo faltaría llamar a este proc. almacenado como comprobación o
convertirlo en trigger, pero la lógica ya está definida.

Salu2,
Jorge


"Pablo Guevara" wrote in message
news:OjD32$
Necesito hacer una consulta con registros que tienen una fecha inicial y
fecha final. Me piden que no se pueda ingresar una fecha que ya este
incluida en el periodo, poer ejemplo:

Enero 01/2005 - Diciembre 31/2005

Si intentamos ingresar :

Julio 01/2005 Julio 21/2006

el sistema confirma que la fecha se sobrepone a una ya existente.

¿Alguna idea?

Thx

Pablo

+++


Respuesta Responder a este mensaje
#2 Pablo Guevara
25/02/2005 - 02:41 | Informe spam
Jorge,

Mil gracias, me ha sido de mucha utilidad.

Slds.

Pablo

+++
"Jorge Bustos" escribió en el mensaje
news:
create table t (i datetime, f datetime)
insert into t values ('20050101','20050131')

insertarse

insertar y uno concreto que estés vigilando en la tabla:
1)
i--f
@
por ejemplo del 15 de enero al 15 de febrero

2)
i--f
@
por ejemplo del 31 de diciembre anterior al 15 de enero

3)
i--f
@
por ejemplo del 10 al 20 de enero

4)
i--f
@
por ejemplo del 1 de diciembre anterior al 1 de febrero

Para localizar estos posibles casos de intersección hay que realizar estas
consultas:
(OJO: pseudocódigo para entender mejor la exlicación. el código final va
en
el procedimiento)
1) select * from t where t.i<=@ni<=t.f
2) select * from t where t.i<=@nf<=t.f
3) cualquiera de las comprobaciones 1) y 2) reconocen esta intersección
4) serían dos consultas:
select * from t where @ni<=t.i<=@nf
select * from t where @ni<=t.f<=@nf
Pero con comprobar que o bien i o bien f estén dentro de el rango entre ni
y
nf basta para saber que se solapan

En resumen, para comprobar si un rango está ocupado basta con:

create procedure disponible
@ni datetime, @nf datetime
as
begin
select count(*) from t
where
(t.i<=@ni and @ni<=t.f)
or
(t.i<=@nf and @nf<=t.f)
or
(@ni<=t.i and t.i<=@nf)
end

Si la cuenta devuelta es mayor que cero el periodo está ocupado.

Puedes comprobar los 6 casos posibles (4 intersecciones de arriba, y dos
que
no tienen intersección)
exec disponible '20050115','20050215'
exec disponible '20041231','20050115'
exec disponible '20050110','20050120'
exec disponible '20041201','20050201'
exec disponible '20041201','20041215'
exec disponible '20051201','20051215'

Ahora solo faltaría llamar a este proc. almacenado como comprobación o
convertirlo en trigger, pero la lógica ya está definida.

Salu2,
Jorge


"Pablo Guevara" wrote in message
news:OjD32$
Necesito hacer una consulta con registros que tienen una fecha inicial y
fecha final. Me piden que no se pueda ingresar una fecha que ya este
incluida en el periodo, poer ejemplo:

Enero 01/2005 - Diciembre 31/2005

Si intentamos ingresar :

Julio 01/2005 Julio 21/2006

el sistema confirma que la fecha se sobrepone a una ya existente.

¿Alguna idea?

Thx

Pablo

+++






Respuesta Responder a este mensaje
#3 Alejandro Mesa
25/02/2005 - 22:31 | Informe spam
Pablo,

Puedes usar un trigger que chequee si existe algun rango que se sobrepone a
alguno ya existente. La pregunta clave es:

Existe una fila insertada que empieza antes que una existente termine y a su
vez termine antes que una existente empieze?, si es asi entonces rollback la
trasaccion. Puedes usar >= y <= para que no empieze en el mismo momento que
otra termina.

Ejemplo:

use northwind
go

create table dbo.t(
colA int not null identity unique,
fecha_inicial datetime not null,
fecha_final datetime not null,
constraint chk_fecha_inicial_fecha_final check(fecha_inicial < fecha_final)
)
go

create trigger dbo.utr_t_for_ins_upd on dbo.t
for insert, update
as
if @@rowcount = 0 return

if exists(select * from inserted as i join t on i.colA <> t.colA and
i.fecha_inicial < t.fecha_final and i.fecha_final > t.fecha_inicial)
begin
raiserror('Fechas sobrepuestas.', 16, 1)
rollback transaction
return
end
go

declare @d datetime

set @d = getdate()

insert into t (fecha_inicial, fecha_final) values(@d, dateadd(minute, 5, @d))
insert into t (fecha_inicial, fecha_final) values(dateadd(minute, 5, @d),
dateadd(minute,
10, @d))

select * from dbo.t

insert into t (fecha_inicial, fecha_final)
values(dateadd(minute, 9, @d), dateadd(minute, 11, @d))
go

select * from dbo.t
go

drop table dbo.t
go


AMB

"Pablo Guevara" wrote:

Necesito hacer una consulta con registros que tienen una fecha inicial y
fecha final. Me piden que no se pueda ingresar una fecha que ya este
incluida en el periodo, poer ejemplo:

Enero 01/2005 - Diciembre 31/2005

Si intentamos ingresar :

Julio 01/2005 Julio 21/2006

el sistema confirma que la fecha se sobrepone a una ya existente.

¿Alguna idea?

Thx

Pablo

+++



Respuesta Responder a este mensaje
#4 Pablo Guevara
26/02/2005 - 13:51 | Informe spam
Alejandro,

Muchas gracias. en base a la respuesta de jorge hice un Trigger muy
parecido al que pones de ejemplo.

My agradecido.

Slds.

Pablo

+++
"Alejandro Mesa" escribió en el
mensaje news:
Pablo,

Puedes usar un trigger que chequee si existe algun rango que se sobrepone
a
alguno ya existente. La pregunta clave es:

Existe una fila insertada que empieza antes que una existente termine y a
su
vez termine antes que una existente empieze?, si es asi entonces rollback
la
trasaccion. Puedes usar >= y <= para que no empieze en el mismo momento
que
otra termina.

Ejemplo:

use northwind
go

create table dbo.t(
colA int not null identity unique,
fecha_inicial datetime not null,
fecha_final datetime not null,
constraint chk_fecha_inicial_fecha_final check(fecha_inicial <
fecha_final)
)
go

create trigger dbo.utr_t_for_ins_upd on dbo.t
for insert, update
as
if @@rowcount = 0 return

if exists(select * from inserted as i join t on i.colA <> t.colA and
i.fecha_inicial < t.fecha_final and i.fecha_final > t.fecha_inicial)
begin
raiserror('Fechas sobrepuestas.', 16, 1)
rollback transaction
return
end
go

declare @d datetime

set @d = getdate()

insert into t (fecha_inicial, fecha_final) values(@d, dateadd(minute, 5,
@d))
insert into t (fecha_inicial, fecha_final) values(dateadd(minute, 5, @d),
dateadd(minute,
10, @d))

select * from dbo.t

insert into t (fecha_inicial, fecha_final)
values(dateadd(minute, 9, @d), dateadd(minute, 11, @d))
go

select * from dbo.t
go

drop table dbo.t
go


AMB

"Pablo Guevara" wrote:

Necesito hacer una consulta con registros que tienen una fecha inicial y
fecha final. Me piden que no se pueda ingresar una fecha que ya este
incluida en el periodo, poer ejemplo:

Enero 01/2005 - Diciembre 31/2005

Si intentamos ingresar :

Julio 01/2005 Julio 21/2006

el sistema confirma que la fecha se sobrepone a una ya existente.

¿Alguna idea?

Thx

Pablo

+++



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