Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Firebird e Interbase (https://www.clubdelphi.com/foros/forumdisplay.php?f=19)
-   -   Funciones que no tolera firebird 2.5 (https://www.clubdelphi.com/foros/showthread.php?t=82393)

novato_erick 02-03-2013 22:13:40

Funciones que no tolera firebird 2.5
 
Hola chicos como están nuevamente?

tengo que obtener un resultado como este:

Cita:

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:
Código SQL [-]
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:

Código SQL [-]
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:

Cita:

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:
Código SQL [-]
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

Código SQL [-]
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:

Código SQL [-]
   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:

Cita:

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:

Cita:

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 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

Código SQL [-]
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

1 Archivos Adjunto(s)
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

Cita:

Empezado por Casimiro Notevi (Mensaje 455913)
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
Código SQL [-]
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

Código SQL [-]
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


La franja horaria es GMT +2. Ahora son las 03:49:10.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi