PDA

Ver la Versión Completa : Consulta por días laborables, sábados y domingos


judoboy
02-07-2003, 10:40:00
Hola tengo que calcular la nómina de los empleados de una fábrica. La nómina la calculo a partir de los precios que tiene asignados cada trabajador, por Hora Normal, Hora Extra, Hora Sábado, Hora Domingo, y el precio que se indica en cada ficha del empleado.

Como puedo hacer para distinguir mediante una consulta SQL, los días si son laborables, sábados o domingos?

Alguien sabe como puede hacer la consulta que necesito?


Gracias de antemano.

javiermorales
02-07-2003, 15:09:01
Yo he tenido que realizar la misma labor. A parte de controlar los Sábados y Domingos, deberías controlar los festivos, ya que se cobrarán como horas extras. Para este último caso, yo me cree una tabla donde se indicaban por parte del usuario los días que se consideraban festivos, ya que cambia segun la comunidad e incluso el ramo de que se trate.

En cuanto a saber que días son Sábados o Domingos, depende del motor de base de datos que utilices, ya que en determinados motores, puedes obtener directamente el día de la semana y utilizar los condicionales "iif", para saber que precio dia/hora debes utilizar.

Si quieres mañana te paso la sentencia completa que utilizo yo, ya que ahora no la tengo, para que te sirva de guía. De todas maneras adelántame que motor utilizas.

Un saludo.

judoboy
08-07-2003, 15:15:55
Hola javiermorales, gracias por responder.

Te comento yo utilizo Interbase conectada mediante BDE, espero tu ayuda.

javiermorales
09-07-2003, 11:23:13
Buenos Días, siento haber tardado, te paso las dos SQL que utilizo para el cálculo de horas normales, extras y de festivos, ya que en mi caso se cobra a diferente precio estos tres tipos (incluso tengo un intérvalo de precios de horas extras, ya que no cobran lo mismo, y depende del trabajador, todas las horas extras. Bueno te lo paso y explico:

//Horas Normales
SELECT CNM_ITE, CNM_MES, CNM_AÑO,
Sum(IIf(([CNM_DSM]<>"SABADO" And [CNM_DSM]<>"DOMINGO"),
IIf(([CNM_HTA]-[PER_HPD])<0,[CNM_HTA],[PER_HPD]),0)) AS HTA,
Sum(IIf(([CNM_DSM]<>"SABADO" And [CNM_DSM]<>"DOMINGO"),
IIf(([CNM_HTA]-[PER_HPD])<=0,0,(IIf(([CNM_HTA]-[PER_HPD])>[PER_HF1],[PER_HF1],([CNM_HTA]-[PER_HPD])))),0)) AS HE1, Sum(IIf(([CNM_DSM]<>"SABADO" And [CNM_DSM]<>"DOMINGO"),IIf(([CNM_HTA]-[PER_HPD])<=0,0,(IIf(([CNM_HTA]-[PER_HPD])>[PER_HF1],([CNM_HTA]-[PER_HPD]-[PER_HF1]),0))),0)) AS HE2
FROM CNM, PER
WHERE CNM_ITE=:iteter AND CNM_AÑO=:ano AND CNM_MES=:mescalc AND CNM_ITE=PER_ITE AND CDate(Str([CNM_DIA])+'/'+Str([CNM_MES])+'/'+Str([CNM_AÑO])) NOT IN (SELECT CAL_FECHA FROM CAL) AND
CDate(Str([CNM_DIA])+'/'+Str([CNM_MES])+'/'+Str([CNM_AÑO])) NOT IN (SELECT CAP_FECHA FROM CAP WHERE CAP_ITE=CNM_ITE)
GROUP BY CNM_ITE, CNM_MES, CNM_AÑO;

Como ves obtengo el cálculo de un mes en concreto. Respecto a CNM_DSM, es un campo calculado en tiempo de ejecución, cuando introducen las hora trabajadas en una fecha, con esa fecha, le calculo el dia de la semana en Delphi utilizando el DayofWeek(fecha), teniendo en cuenta que te devuelve un numérico del 1 al 7 y el 1 es Domingo y el 7 es Sábado.

//Horas Festivas
SELECT CNM_ITE, CNM_MES, CNM_AÑO, Sum([CNM_HTA]) AS HFE
FROM CNM, PER
WHERE CNM_AÑO=:ano and CNM_MES=:mescalc and PER_ITE=:iteter and CNM_ITE=PER_ITE and ( [CNM_DSM]="SABADO" or [CNM_DSM]="DOMINGO" or CDate(Str([CNM_DIA])+'/'+Str([CNM_MES])+'/'+Str([CNM_AÑO])) IN (SELECT CAL_FECHA FROM CAL) or CDate(Str([CNM_DIA])+'/'+Str([CNM_MES])+'/'+Str([CNM_AÑO])) IN (SELECT CAP_FECHA FROM CAP WHERE CAP_ITE=CNM_ITE) )
GROUP BY CNM_ITE, CNM_MES, CNM_AÑO;

Espero que te ayude y cualquier duda sobre las SQL que te paso, me la comentas.

Aprendiz
10-07-2003, 12:24:01
Si trabajas con Interbase no tendrás la clausula 'iif' que te indica javiermorales. De todas maneras puedes reaprovechar su consulta si creas un procedimiento almacenado.

Un procedimiento almacenado una vez creado lo puedes utilizar como una tabla más en una consulta SQL, por lo tanto podrias hacer que el procedimiento almacenado te devolviese directamente los resultados para un empleado de los importes a cobrar por dias normales en un campo, por fines de semana en otro, y por extras en otros.

Debes utilizar dentro del procedimiento almacenado la clausula SUSPEND para que te vaya devolviendo los valores.

Saludos

judoboy
10-07-2003, 13:21:54
Estoy un poco perdido, no se como funcionan los procedimientos almacenados.

Me lo podrías explicar, o decirme donde puedo encontrar información.

Aprendiz
10-07-2003, 16:15:31
A ver un procedimiento almacenado es eso un procedimiento que guardas directamente en la base de datos.

Cuando quieres hacer una consulta muy bestia, o una función que te realice una serie de cálculo muy costosos, etc., en vez de hacerlo en local, creas un procedimiento almacenado (stored procedure) que realice esa función directamente en el servidor con lo que aceleras mucho la velocidad por que lo único que tu haces es llamar al procedimiento con los parámetros, si fuese necesario, y obtener directamente los resultados.

Un procedimiento almacenado puede hacer de todo, simplemente hacer unos cálculos y no devolver nada, o un solo resultado, o muchos. En el caso que quieras devolver muchos podemos aprovecharnos y utilizarlo como si fuese una tabla más de nuestra base de datos.



Ejemplo:

set term /;
create procedure HOMOLOGACION
returns (HOMOLOGADO SMALLINT, CODIGO_PROVEEDOR VARCHAR(10))
as
begin
/* NO HOMOLOGADOS */
for select DISTINCT PRO.CODIGO_PROVEEDOR
from PROVEEDORES PRO
where (PRO.FECHA_CADUCIDAD<=F_DATE() or CER.FECHA_CADUCIDAD is null)
into :CODIGO_PROVEEDOR
do
begin
HOMOLOGADO=0;
SUSPEND;
end
/* HOMOLOGADOS */
for select DISTINCT PRO.CODIGO_PROVEEDOR
from PROVEEDORES PRO
where PRO.FECHA_CADUCIDAD>F_DATE()
into :CODIGO_PROVEEDOR
do
begin
HOMOLOGADO=1;
SUSPEND;
end
end;/
set term ;/



La clausula SUSPEND hace que el procedimiento devuelva los valores directamente como si de una tabla se tratase, así este procedimiento devolverá 'n' resultados.

Con este procedimiento podrias hacer cosas como:

SELECT CODIGO_PROVEEDOR,HOMOLOGADO
FROM HOMOLOGACION

Saludos