Consulta rango de tiempos

15/08/2009 - 18:03 por kojikabutosv | Informe spam
He estado tratando de implementar una consulta pero no ya no doy "bola",
como puedo saber si un rango de horas dadas se encuentran en la base de
datos, por ejemplo:

en la tabla tengo:

registroid codemp horainicio horafinal

1 20 08:00 09:05
2 21 13:00 14:05


pero quiero hacer la consulta que si yo envio

para el empleado 20 si yo le envio 08:30 a 9:00 me devuelva que ya
existe ese horario ocupado, pero si le devuelvo 09:10 a 10:00 que
aparezca disponible.

agradezco mucho su ayuda puesto que trato con varios between pero no me
devuelve los datos correctos.

Saludos,

Preguntas similare

Leer las respuestas

#1 Alejandro Mesa
16/08/2009 - 18:28 | Informe spam
Que version de SQL Server usas?

Veamos que tienen en comun estos rangos.

A1 A2
-

B1 B2 B3 B4

B5 B6

Suponiendo que el rango A1:A2 es el rango que se almacena en la db
horainicio:horafinal, y que este rango contine cuanto maximo hasta las 23:59,
ademas los rangos Bx:By son los rangos que pasas como parametro, entonces
tenemos que todos los rangos que se solapan cumplen que "Bx <= horafinal" y
"By >= horainicio". En palabras seria algo asi como el rango que busco empiza
antes de que el rango en la db termine, y el rango que busco termina despues
que el rango de la db haya empezado.


use tempdb;
go

declare @t table (
registroid int not null unique,
codemp int not null,
horainicio varchar(15) not null,
horafinal varchar(15) not null
);

insert into @t values(1,20,'08:00','09:05');
insert into @t values(2,21,'13:00','14:05');

select * from @t;

declare @st datetime, @et datetime;
declare @codemp int;

select @codemp = 20, @st = '08:30:00', @et = '09:00:00';

select @codemp, @st, @et, 'ya existe'
where exists (
select *
from @t
where codemp = @codemp and @st <= horafinal and @et >= horainicio
);

select @st = '09:10:00', @et = '10:00:00';

select @codemp, @st, @et, 'disponible'
where not exists (
select *
from @t
where codemp = @codemp and @st <= horafinal and @et >= horainicio
);
GO

Como ves, se usa una fecha de referencia, en este caso 01/01/1900 para poder
trabajar con los datos de tiempo.

Si estuvieses usando SQL Server 2008, entonces pudieras usar el nuevo tipo
de data TIME.


AMB


"kojikabutosv" wrote:

He estado tratando de implementar una consulta pero no ya no doy "bola",
como puedo saber si un rango de horas dadas se encuentran en la base de
datos, por ejemplo:

en la tabla tengo:

registroid codemp horainicio horafinal

1 20 08:00 09:05
2 21 13:00 14:05


pero quiero hacer la consulta que si yo envio

para el empleado 20 si yo le envio 08:30 a 9:00 me devuelva que ya
existe ese horario ocupado, pero si le devuelvo 09:10 a 10:00 que
aparezca disponible.

agradezco mucho su ayuda puesto que trato con varios between pero no me
devuelve los datos correctos.

Saludos,


Respuesta Responder a este mensaje
#2 Carlos M. Calvelo
17/08/2009 - 10:33 | Informe spam
Hola Alejandro,

On 16 aug, 18:28, Alejandro Mesa
wrote:
Que version de SQL Server usas?

Veamos que tienen en comun estos rangos.

A1 A2
-

B1 B2 B3 B4

B5 B6

Suponiendo que el rango A1:A2 es el rango que se almacena en la db
horainicio:horafinal, y que este rango contine cuanto maximo hasta las 23:59,
ademas los rangos Bx:By son los rangos que pasas como parametro, entonces
tenemos que todos los rangos que se solapan cumplen que "Bx <= horafinal" y
"By >= horainicio". En palabras seria algo asi como el rango que busco empiza
antes de que el rango en la db termine, y el rango que busco termina despues
que el rango de la db haya empezado.

use tempdb;
go

declare @t table (
registroid int not null unique,
codemp int not null,
horainicio varchar(15) not null,
horafinal varchar(15) not null
);

insert into @t values(1,20,'08:00','09:05');
insert into @t values(2,21,'13:00','14:05');

select * from @t;

declare @st datetime, @et datetime;
declare @codemp int;

select @codemp = 20, @st = '08:30:00', @et = '09:00:00';

select @codemp, @st, @et, 'ya existe'
where exists (
select *
from @t
where codemp = @codemp and @st <= horafinal and @et >= horainicio
);

select @st = '09:10:00', @et = '10:00:00';

select @codemp, @st, @et, 'disponible'
where not exists (
select *
from @t
where codemp = @codemp and @st <= horafinal and @et >= horainicio
);
GO




'Pequeño' detalle: estos controles funcionan para inserts. Cuando
se hacen updates no se debe incluir en el control el registro
que se está actualizando:

...
where
exists (
select *
from @t
where codemp = @codemp and
registroid <> @registroid and -- <<<<<< --
@st <= horafinal and @et >= horainicio
);

Para inserts se puede asignar a @registro un valor 'imposible' para
que esa condición evalue siempre 'true'.

Estos controles deberían además ser programados en una función
y utilizar esta función en un check (constraint).
O en triggers, que será más eficiente para los casos de inserts
o updates 'set at a time'.

Otra condición necesaria para esto funcione *siempre* es que aquella
clave que se utilize para eso, en este caso {registroid}, no debe
ser actualizable.

Saludos,
Carlos
Respuesta Responder a este mensaje
#3 Carlos M. Calvelo
17/08/2009 - 10:39 | Informe spam
Hola otra vez Alajandro,

Otro pequeño detalle: se debe tener también un constraint
'horainicio <= horafinal'. La lógica que tu has explicado
depende de ello.

Saludos,
Carlos
Respuesta Responder a este mensaje
#4 Alejandro Mesa
17/08/2009 - 17:04 | Informe spam
Hola Carlos,

Gracias, creo que es importante lo que comentastes.

Solamente chequeando durante la operacion de insert no es suficiente, se
debe tener algun mecanismo que chequee la solapacion (lo dije bien?) de
rangos a nivel de base de dato, puede ser un trigger u otro mecanismo. A
proposito, hay una forma sugerida por un colega SQL Server MVP, Alexander
Kuznetsov, donde se hace uso de la denormalizacion para crear restricciones
de clave foranea autoreferenciales. Aca te paso el link, porque se que tu vas
a apreciar este articulo.

Denormalizing to enforce business rules: Part 1.
http://sqlblog.com/blogs/alexander_...art-1.aspx


AMB


"Carlos M. Calvelo" wrote:

Hola otra vez Alajandro,

Otro pequeño detalle: se debe tener también un constraint
'horainicio <= horafinal'. La lógica que tu has explicado
depende de ello.

Saludos,
Carlos



Respuesta Responder a este mensaje
#5 kojikabutosv
17/08/2009 - 17:54 | Informe spam
Gracias Alejandro y Carlos voy a estudiar lo que me plantean, según
entiendo puedo meter este código en una función verdad? para que me
devuelva un valor para saber si existe o no.

Saludos y éxitos!!!

Carlos M. Calvelo escribió:
Hola otra vez Alajandro,

Otro pequeño detalle: se debe tener también un constraint
'horainicio <= horafinal'. La lógica que tu has explicado
depende de ello.

Saludos,
Carlos


Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida