PDA

Ver la Versión Completa : Funciones que no tolera firebird 2.5


novato_erick
02-03-2013, 22:13:40
Hola chicos como están nuevamente?

tengo que obtener un resultado como este:


id_depto---id_empleado----Fecha------HoraEntrada-----HoraSalida------HoraEntrada1---HoraSalida1
1-----------5-----------19/09/2012------08:31:00------12:38:00--------14:30:00------18:50:00
1-----------7-----------19/09/2012------08:19:00------12:34:00--------14:26:00------19:24:00
1-----------12----------19/09/2012------08:06:00------15:22:00 --------NULL-----------NULL
1-----------13----------19/09/2012------07:03:00------17:08:00 ------- NULL-----------NULL


La informacion se obtiene de las siguientes tablas:

CREATE TABLE TMARCACIONES (
ID_MARCAS INTEGER NOT NULL,
ID_EMPLEADOS INTEGER NOT NULL,
HORA TIMESTAMP DEFAULT 'NOW' NOT NULL);


ALTER TABLE TMARCACIONES ADD PRIMARY KEY (ID_MARCAS);


SET TERM ^ ;

CREATE TRIGGER BI_TMARCACIONES_ID_MARCAS FOR TMARCACIONES
ACTIVE BEFORE INSERT
POSITION 0
AS
BEGIN
IF (NEW.ID_MARCAS IS NULL) THEN
NEW.ID_MARCAS = GEN_ID(TMARCACIONES_ID_MARCAS_GEN, 1);
END^



ahora trato de hacerlo con la siguiente consulta:


WITH HORASEMPL AS
(
SELECT ID_EMPLEADOS, HORA, ROW_NUMBER() OVER (PARTITION BY ID_EMPLEADOS ORDER BY HORA) AS IDE
FROM TMARCACIONES WHERE CAST(HORA as Date) = :pFecha
)
SELECT
he.IDEMPLEADO, CAST(he.HORAMARCA as Date) AS Fecha, CAST(he.HORAMARCA as time) As HoraEntrada, CAST(he.HORAMARCA as time) As HoraSalidaAlmuerzo
,CAST(he.HORAMARCA as time) As HoraEntradaAlmuerzo,CAST(he.HORAMARCA as time) As HoraSalida = CASE
WHEN CAST(HORA as TIME) = CAST(f.HORA as TIME) then NULL
WHEN CAST(HORA as TIME) = CAST(s.HORA as TIME) then NULL
ELSE CAST(HORA as TIME)
END
FROM HORASEMPL he
LEFT JOIN (SELECT id_empleados, MIN(HoraMarca) HoraMarca FROM HORASEMPL WHERE IDE > 1 GROUP BY IdEmpleado)as h ON h.id_empleados = he.id_empleados
LEFT JOIN (SELECT id_empleados, MIN(HoraMarca) HoraMarca FROM HORASEMPL WHERE IDE > 2 GROUP BY IdEmpleado) AS f ON f.id_empleados = he.id_empleados
LEFT JOIN (SELECT id_empleados, max(HoraMarca) HoraMarca FROM HORASEMPL WHERE IDE > 1 GROUP BY IdEmpleado) AS g ON g.id_empleados = he.id_empleados

ORDER BY he.IDEMPLEADO


alguna parte esta mal porque me manda lo siguiente:


Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 3, column 46.
(.


no se a que se deba o si alguien conoce alguna forma de hacerlo mejor...

Saludos


novato_erick

Caral
02-03-2013, 22:44:15
Hola
No entiendo bien la sentencia sql, pero me parece que la segunda parte seria asi:

WITH HORASEMPL AS
(
SELECT ID_EMPLEADOS, HORA, ROW_NUMBER() OVER (PARTITION BY ID_EMPLEADOS ORDER BY HORA) AS IDE
FROM TMARCACIONES WHERE CAST(HORA as Date) = Fecha
)
SELECT
he.IDEMPLEADO, CAST(he.HORAMARCA as Date) AS Fecha, CAST(he.HORAMARCA as time) As HoraEntrada, CAST(he.HORAMARCA as time) As HoraSalidaAlmuerzo
,CAST(he.HORAMARCA as time) As HoraEntradaAlmuerzo,CAST(he.HORAMARCA as time) As HoraSalida = CASE
WHEN CAST(HORA as TIME) = CAST(f.HORA as TIME) then NULL
WHEN CAST(HORA as TIME) = CAST(s.HORA as TIME) then NULL
ELSE CAST(HORA as TIME)
END

LEFT JOIN (SELECT id_empleados, MIN(HoraMarca) HoraMarca FROM HORASEMPL WHERE IDE > 1 GROUP BY IdEmpleado)as h ON h.id_empleados = he.id_empleados
LEFT JOIN (SELECT id_empleados, MIN(HoraMarca) HoraMarca FROM HORASEMPL WHERE IDE > 2 GROUP BY IdEmpleado) AS f ON f.id_empleados = he.id_empleados
LEFT JOIN (SELECT id_empleados, max(HoraMarca) HoraMarca FROM HORASEMPL WHERE IDE > 1

FROM HORASEMPL he

GROUP BY IdEmpleado) AS g ON g.id_empleados = he.id_empleados
ORDER BY he.IDEMPLEADO
Saludos

novato_erick
02-03-2013, 23:03:51
Que tal caral como estas?

Trataré de explicar mi sentencia


WITH HORASEMPL AS /*Esta es mi tabla Temporal creada*/
(
SELECT ID_EMPLEADOS, HORA, ROW_NUMBER() OVER (PARTITION BY ID_EMPLEADOS ORDER BY HORA) AS IDE --* ROW_NUMBER() OVER (PARTITION BY ID_EMPLEADOS ORDER BY HORA) AS IDE
/* Aquí es donde en teoria en sql Server funciona pero en firebird no estoy muy claro pienso que es igual */
FROM TMARCACIONES WHERE CAST(HORA as Date) = :Fecha /* Parámetro de Búsqueda por Fecha ejemplo solo quiero las marcaciones de la fecha designada*/
)
SELECT
he.IDEMPLEADO, CAST(he.HORAMARCA as Date) AS Fecha, CAST(he.HORAMARCA as time) As HoraEntrada, CAST(he.HORAMARCA as time) As HoraSalidaAlmuerzo
,CAST(he.HORAMARCA as time) As HoraEntradaAlmuerzo,CAST(he.HORAMARCA as time) As HoraSalida = CASE
WHEN CAST(HORA as TIME) = CAST(f.HORA as TIME) then NULL
WHEN CAST(HORA as TIME) = CAST(s.HORA as TIME) then NULL
ELSE CAST(HORA as TIME)
END /*Aqui recuerda por lo general el empleado realiza cuatro (4) marcaciones diferentes en el dia trato de traer con el left join dichas marcaciones llevandolas todo a mi tabla temporar
FROM HORASEMPL he
LEFT JOIN (SELECT id_empleados, MIN(HoraMarca) HoraMarca FROM HORASEMPL WHERE IDE > 1 GROUP BY IdEmpleado)as h ON h.id_empleados = he.id_empleados
LEFT JOIN (SELECT id_empleados, MIN(HoraMarca) HoraMarca FROM HORASEMPL WHERE IDE > 2 GROUP BY IdEmpleado) AS f ON f.id_empleados = he.id_empleados
LEFT JOIN (SELECT id_empleados, max(HoraMarca) HoraMarca FROM HORASEMPL WHERE IDE > 1 GROUP BY IdEmpleado) AS g ON g.id_empleados = he.id_empleados

ORDER BY he.IDEMPLEADO


Lo he hecho de una manera simple por ejemplo:


select DISTINCT d.DEPARTAMENTO,
e.ID_EMPLEADOS,
e.CEDULA_EMPL,
e.NOMBRE_EMPL Nombre,
e.APELLIDO1_EMPL Apellido,
e.APELLIDO2_EMPL "Segundo Apellido",
e.COD_CLAVE,
CAST(m.HORA as time) Marcacion
from
TEMPLEADOS e,
TEMP_DEPART ep,
TDEPARTAMENTOS d,
TMARCACIONES m
where e.ID_EMPLEADOS = m.ID_EMPLEADOS
and e.ID_EMPLEADOS =:idE
and e.ID_EMPLEADOS = ep.ID_EMPLEADOS
and d.ID_DEPTOS = ep.ID_DEPTOS
and CAST(m.HORA as DATE) = :fechaE
group by d.DEPARTAMENTO,e.ID_EMPLEADOS,
e.CEDULA_EMPL,
e.ID_EMPLEADOS,
e.NOMBRE_EMPL,
e.APELLIDO1_EMPL,
e.APELLIDO2_EMPL,
e.COD_CLAVE,m.HORA


pero me muestra mas o menos este resultado que no es el deseado:


DEPARTAMENTO----ID_EMPLEADO---CED_EMPLEADO----NOMBRE----APELLIDO---MARCACION
CALZADO-------------44--------------8-555-55--------MARIA-----VERGARA----09:58:27
CALZADO-------------44--------------8-555-55--------MARIA-----VERGARA----12:01:51
CALZADO-------------44--------------8-555-55--------MARIA-----VERGARA----13:00:42
CALZADO-------------44--------------8-555-55--------MARIA-----VERGARA----19:56:17



y necesito esto:


DEPARTAMENTO----ID_EMPLEADO---CED_EMPLEADO----NOMBRE----APELLIDO---HORAENTRADA----HORASALIDAALMUERZO----HORAENTRADAALMUERZO-------SALIDA
CALZADO-------------44--------------8-555-55--------MARIA-----VERGARA-----09:58:27-----------12:01:51------------------13:00:42-----------------19:56:17


Aun no lo he logrado



Saludos

Caral
02-03-2013, 23:23:00
Hola
No se como tienes las tablas.
Tampoco entiendo bien el sql (es muy avanzado para mi):o.
Yo hice un programa de marcado de entradas y salidas de los empleados y no tengo tantas cosas raras como tu :D.
Te paso el link del programa (http://www.clubdelphi.com/foros/attachment.php?attachmentid=2508&d=1355419120) tal vez te ayude de algo.
Usa un componente para cargar una foto, ya que toma la foto del empleado cada vez que marca (para evitar que hagan trampa).
Saludos

novato_erick
02-03-2013, 23:30:44
Caral Agradezco mucho Tu colaboración le hechare un vistazo... pero aun necesito realizar la consulta en sql..

En caso que encuentre solución presentaré la solución...

Saludos

Casimiro Notevi
02-03-2013, 23:40:25
WITH ...
(
SELECT ...
)
SELECT ...


Nunca había visto hacer un select de esa forma, ¿with? y dos select seguidos, ¿eso funciona? :confused:

Spynosa
03-03-2013, 10:06:31
Si que funciona Casimiro, creo que desde la version 2.0, echale un vistazo a esto http://www.orafaq.com/node/1879.

Spynosa
03-03-2013, 10:10:00
novato_erick creo que la funcion ROW_NUMBER() no esta soportada en firebird tendras que buscar una similar
mira este enlace por si te sirve http://www.firebirdfaq.org/faq343

Casimiro Notevi
03-03-2013, 11:40:29
Ese enlace es de oracle, no de firebird.

Spynosa
03-03-2013, 11:44:49
pero funciona con firebird

un saludo

Casimiro Notevi
03-03-2013, 11:58:38
¿En la documentación de firebird viene eso?, es que no lo he visto nunca.

Spynosa
03-03-2013, 12:49:02
No se si viene pero te aseguro que funciona en firebird, yo tengo varias consultas
complejas con with y la idea la cogi de esa página

novato_erick
03-03-2013, 18:28:08
Ah si claro casimiro envio este pdf para que veas...

pero aun asi no lo he logrado tengo que documentarme...

saludos

Casimiro Notevi
03-03-2013, 18:47:38
En ese documento no hablan de ningún comando o función que se llame "with",
Y además pone que es para firebird 3, aunque está fechado en 2011 :confused:

cloayza
04-03-2013, 21:30:24
En ese documento no hablan de ningún comando o función que se llame "with",
Y además pone que es para firebird 3, aunque está fechado en 2011 :confused:

Casimiro, ya en la version 2.5 está operativa este tipo de sentencias, no recuerdo si desde la 2.0 en adelante...

Mira el archivo de texto que esta en ?:\Program Files\Firebird\Firebird_2_5\doc\sql.extensions\README.common_table_expressions.txt ahí hay una explicación y ejemplos del uso de esta sentencias que son muy utiles.

Inclusive se puede utilizar recursividad para obtener información.

Saludos cordiales

pacopenin
05-03-2013, 17:07:20
Yo tampoco conocía esa forma de SQL.
http://firebirdsql.su/doku.php?id=recursive. En esta página aparece la sintaxis y algún ejemplo.

Casimiro Notevi
05-03-2013, 17:25:32
Curioso, y está desde la 2.1

fjcg02
05-03-2013, 17:53:46
yo haría algo así, en pseudo código

select EMPLEADOS.Nombre, EMPLEADOS.Apellidos,
max( case when TMARCACIONES.hora entre 8:00 y 9:00 then TMARCACIONES.hora else 0) AS ENTRADA,
max( case when TMARCACIONES.hora entre 12:00 y 13:00 then TMARCACIONES.hora else 0) AS SALIDA_ ALMUERZO,
max( case when TMARCACIONES.hora entre 14:00 y 15:00 then TMARCACIONES.hora else 0) AS ENTRADA_TARDE,
max( case when TMARCACIONES.hora entre 18:00 y 19:00 then hora else 0) AS SALIDA_JORNADA
FROM TMARCACIONES WHERE CAST(HORA as Date) = :Fecha
inner join EMPLEADOS ON EMPLEADOS.ID_EMPLEADOS = TMARCACIONES.ID_EMPLEADOS
group by EMPLEADOS.Nombre, EMPLEADOS.Apellidos


Ni with ni chanflainas. Supongo que es lo mismo que

select TABLA.* from
( select campo1, campo2 from TABLAX bla bla bla ) TABLA
group by bla bla
order by bla bla

Sólo falta ver qué pasa cuando una persona no ficha entre esas horas, excepciones de salidas la médico, etc etc que deberían ser recogidas también.


Espero que te sirva de ayuda.

Un saludo