Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 09-02-2009
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: dic 2003
Ubicación: Zamudio
Posts: 1.369
Poder: 15
fjcg02 Va camino a la fama
Trasnformadas, crosstab, pivot, referencias cruzadas ...

... o como quieras llamarlo.
Os dejo un documento que he escrito. No tengo para pasarlo a pdf, por lo que lo dejo a güevo.
El documento explica qué son y explica un procedimiento almacenado que permite en base a unos parámetros extraer información de una tabla o vista o consulta haciendo la transposición de la información en base al campo que se indica para hacer de 'pivote'.
Espero que le valga a alguien, a mi me ha servido. Si alguien además de serle útil termina el tema de los meses, por favor que lo publique. Espero vuestras opiniones.
Saludos
Archivos Adjuntos
Tipo de Archivo: zip SENTENCIAS PIVOT EN FIREBIRD.zip (10,2 KB, 394 visitas)
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -

Última edición por fjcg02 fecha: 12-02-2009 a las 13:13:13. Razón: Aclarar contenido del documento
Responder Con Cita
  #2  
Antiguo 22-02-2010
mjjj mjjj is offline
Miembro
 
Registrado: mar 2007
Posts: 630
Poder: 11
mjjj Va por buen camino
Que formato tiene el archivo comprimido, NO lo puedo leer.

Saludos
Responder Con Cita
  #3  
Antiguo 22-02-2010
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: dic 2003
Ubicación: Zamudio
Posts: 1.369
Poder: 15
fjcg02 Va camino a la fama
Formato ZIP. Acabo de abrirlo y me funciona.

SAludos
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
Responder Con Cita
  #4  
Antiguo 22-02-2010
mjjj mjjj is offline
Miembro
 
Registrado: mar 2007
Posts: 630
Poder: 11
mjjj Va por buen camino
El ZIP no tiene problema, es el archivo que esta comprimido.
Responder Con Cita
  #5  
Antiguo 23-02-2010
Delfino Delfino is offline
Miembro
 
Registrado: jul 2003
Ubicación: Madrid
Posts: 974
Poder: 15
Delfino Va por buen camino
Cita:
Empezado por fjcg02 Ver Mensaje
No tengo para pasarlo a pdf
Si lo abres con el Open Office lo exportas a PDF en un click
__________________
¿Microsoft? No, gracias..
Responder Con Cita
  #6  
Antiguo 24-02-2010
Gallosuarez Gallosuarez is offline
Miembro
 
Registrado: feb 2007
Posts: 92
Poder: 11
Gallosuarez Va por buen camino
Otra solución..

Srs.

Propongo otra solución mas rápida y robusta (creo yo). Utilizo CTE (Common Table Expressions). Funciona para la versión 2.1 en adelante.
Código SQL [-]
WITH USUARIO_TOTAL AS (
  SELECT USUARIO, TIPO, SUM(IMPORTE) AS TOTAL, COUNT(*) AS QTY
  FROM USUARIOS
  GROUP BY USUARIO, TIPO
)
SELECT DISTINCT U.USUARIO, GASTO.QTY AS GASTO_QTY, GASTO.TOTAL AS GASTO, 
  INGRESO.QTY AS INGRESO_QTY, INGRESO.TOTAL AS INGRESO
FROM USUARIOS U
  LEFT JOIN USUARIO_TOTAL GASTO
    ON U.USUARIO = GASTO.USUARIO AND GASTO.TIPO = 'Gasto'
  LEFT JOIN USUARIO_TOTAL INGRESO
    ON U.USUARIO = INGRESO.USUARIO AND INGRESO.TIPO = 'Ingreso';
Espero que sirva de algo...

Saludos

Gerardo Suárez Trejo
Responder Con Cita
  #7  
Antiguo 24-02-2010
IVAND IVAND is offline
Miembro
 
Registrado: may 2003
Ubicación: ECUADOR
Posts: 397
Poder: 15
IVAND Va por buen camino
me parece muy bien ahh el sp

para tablas cruzadas yo utilizo un componente muy bueno q es de devexpress gracias por tu aporte
__________________
IVAND
Responder Con Cita
  #8  
Antiguo 25-02-2010
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: dic 2003
Ubicación: Zamudio
Posts: 1.369
Poder: 15
fjcg02 Va camino a la fama
Cita:
Empezado por Gallosuarez Ver Mensaje
Srs.

Propongo otra solución mas rápida y robusta (creo yo). Utilizo CTE (Common Table Expressions). Funciona para la versión 2.1 en adelante.
Código SQL [-]
WITH USUARIO_TOTAL AS (
  SELECT USUARIO, TIPO, SUM(IMPORTE) AS TOTAL, COUNT(*) AS QTY
  FROM USUARIOS
  GROUP BY USUARIO, TIPO
)
SELECT DISTINCT U.USUARIO, GASTO.QTY AS GASTO_QTY, GASTO.TOTAL AS GASTO, 
  INGRESO.QTY AS INGRESO_QTY, INGRESO.TOTAL AS INGRESO
FROM USUARIOS U
  LEFT JOIN USUARIO_TOTAL GASTO
    ON U.USUARIO = GASTO.USUARIO AND GASTO.TIPO = 'Gasto'
  LEFT JOIN USUARIO_TOTAL INGRESO
    ON U.USUARIO = INGRESO.USUARIO AND INGRESO.TIPO = 'Ingreso';
Espero que sirva de algo...

Saludos

Gerardo Suárez Trejo
Está muy bien, pero sigues necesitando saber previamente cuantos valores de TIPO tienes para sacar los datos. Imaginate que en el campo tipo tienes los valores UNO, DOS, TRES, CUATRO, CINCO, o los que te de la gana.

¿ Cómo pones las columnas siguientes sin modificar tu código ?
USUARIO, UNO, DOS, TRES, CUATRO, CINCO
Queda sin resolver el problema.

Por otro lado hay componentes como los de devexpress y otros que te permiten hacerlo, incluso creo que fastreport también tiene un componente para generar listados de esta manera, pero bajo mi punto de vista, prefiero poner la información en pantalla y que el usuario laimprima cuando realmente lo necesite. Ahora, mi experiencia con ellos no ha sido muy buena - no me refiero al componente de devexpress ya que no lo conozco - .
Ahora, esta solución es gratis y no necesitas soltar eurakos o dolares por delante.

Saludos
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
Responder Con Cita
  #9  
Antiguo 19-09-2012
MDante MDante is offline
Registrado
 
Registrado: sep 2012
Posts: 3
Poder: 0
MDante Va por buen camino
Consulta

Hola fjcg02 soy un novato en programación de bases de datos hace tiempo que busco resolver el problema de presentar información de esta manera

Código:
Clavealumno     horaentrada           diames1   diames2   diames3   diames4   hasta el dia 31 del X mes

1                 8:30 am             8:25am    8:20am    8:50 am   9:28 am   ----------------------->
he utilizado el fragmento de código que compartiste sin embargo hasta el momento no logro hacerlo funcionar mi versión de firebird es la 2.1 y la ejecuto tanto en ibexpert como en firebird maestro y el resultado es el mismo ingrese los datos como sugieres el archivo de word en una tabla llamada testing con columnas llamadas NOMBRE, FECHA, TIPO, IMPORTE y los importe a la base de datos y cada vez que ejecuto el procedimiento desde cualquiera de los dos programas mencionados con los parametros

(TABLA = TESTING )( CAMPO_VISUALIZAR = NOMBRE)( CAMPO_PIVOTE = FECHA) (CONDICIONES = VACIO)

y el resultado no importa que combinación de parámetros use el error siempre es:
Engine Error (code = 335544569):
Dynamic SQL Error.
SQL error code = -206.
Column unknown.
TESTING.
At line 2, column 21.

SQL Error (code = -206):
Column does not belong to referenced table


aunque esto solo era para un proyectito para ganar algunos puntos en la escuela los cuales ya no me gane jeje me esta volviendo loco ya que dure varios días intentando resolver este problema, MS SQL ya lo hace pero me siento a un paso de lograrlo en firebird por eso sigo persistiendo.

tambien he utilizado este tipo de query pero solo me devuelve valores 1 y 0 aunque si con una elegante tabla como yo necesito, esto es en la copia de la base de datos que nos da la escuela
la cual tiene como estructura: TABLA ASISTENCIA
COLUMNAS CLAVEALUMNO(INT) ENTRADA(TIMESTAMP) REGISTROENTRADA(TIMESTAMP)


Código SQL [-]
select distinct 
    clavealumno as clave,
    count( registroentrada) as entrada,
    count( case when extract (day from entrada) = 1 then cast(asistencia.REGISTROENTRADA as date) end ) as dia1,
    count( case when extract (day from entrada) = 2 then cast(entrada as date) end ) as dia2,
    count( case when extract (day from entrada) = 3 then cast(entrada as date) end ) dia3,
    count( case when extract (day from entrada) = 4 then cast(entrada as date) end ) dia4,
    count( case when extract (day from entrada) = 5 then cast(entrada as date) end ) dia5,
    count( case when extract (day from entrada) = 6 then cast(entrada as date) end ) dia6,
    count( case when extract (day from entrada) = 7 then cast(entrada as date) end ) dia7,
    count( case when extract (day from entrada) = 8 then cast(entrada as date) end ) dia8,
    count( case when extract (day from entrada) = 9 then cast(entrada as date) end ) dia9,
    count( case when extract (day from entrada) = 10 then cast(entrada as date) end ) dia10,
    count( case when extract (day from entrada) = 11 then cast(entrada as date) end ) dia11,
    count( case when extract (day from entrada) = 12 then cast(entrada as date) end ) dia12,
    count( case when extract (day from entrada) = 13 then cast(entrada as date) end ) dia13,
    count( case when extract (day from entrada) = 14 then cast(entrada as date) end ) dia14,
    count( case when extract (day from entrada) = 15 then cast(entrada as date) end ) dia15
from asistencia
where 
   (
      (clavealumno < 400)
   and 
      (registroentrada between cast('10/1/2010'as date) and cast('10/15/2010' as date))
   )
group by clavealumno
order by 1

ojala alguien mas que vea el tema aporte sus valiosos conocimientos para lograr hacer un query funcional ya que en ningún lado de la red alguien a compartido algo similar

les dejo una copia de la tabla de la base de datos con información real de entre octubre de 2009 hasta octubre 2011 aprox sobre clave, horario de entrada y registroentrada

https://skydrive.live.com/redir?resi...JwNTFW0rK0bA00

saludos

Última edición por Casimiro Notevi fecha: 19-09-2012 a las 02:38:57.
Responder Con Cita
  #10  
Antiguo 19-09-2012
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 27.162
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Bienvenido a clubdelphi, ¿ya leiste nuestra guía de estilo?, gracias por tu colaboración

Recuerda poner los tags al código fuente, ejemplo:



Gracias
Responder Con Cita
  #11  
Antiguo 19-09-2012
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: dic 2003
Ubicación: Zamudio
Posts: 1.369
Poder: 15
fjcg02 Va camino a la fama
Hola MDante,
vamos por partes porque estás confundiendo algunos términos...
Código SQL [-]
...
    count( registroentrada) as entrada,
    count( case when extract (day from entrada) = 1 then cast(asistencia.REGISTROENTRADA as date) end ) as dia1,
    count( case when extract (day from entrada) = 2 then cast(entrada as date) end ) as dia2,
    count( case when extract (day from entrada) = 3 then cast(entrada as date) end ) dia3,
    count( case when extract (day from entrada) = 4 then cast(entrada as date) end ) dia4,
    count( case when extract (day from entrada) = 5 then cast(entrada as date) end ) dia5,
    count( case when extract (day from entrada) = 6 then cast(entrada as date) end ) dia6,
    count( case when extract (day from entrada) = 7 then cast(entrada as date) end ) dia7,
    count( case when extract (day from entrada) = 8 then cast(entrada as date) end ) dia8,
    count( case when extract (day from entrada) = 9 then cast(entrada as date) end ) dia9,
    count( case when extract (day from entrada) = 10 then cast(entrada as date) end ) dia10,
    count( case when extract (day from entrada) = 11 then cast(entrada as date) end ) dia11,
    count( case when extract (day from entrada) = 12 then cast(entrada as date) end ) dia12,
    count( case when extract (day from entrada) = 13 then cast(entrada as date) end ) dia13,
    count( case when extract (day from entrada) = 14 then cast(entrada as date) end ) dia14,
    count( case when extract (day from entrada) = 15 then cast(entrada as date) end ) dia15
...
Piensa lo que estás haciendo... count "cuenta" las veces que aparece, por lo tanto, te saldrán como valores 1 ó cero, ya que son las veces que aparecen registros con esos datos. Entiendo que en tu tabla hay un registro por día.
Si hay un registro por día te valdría sustituir el count por first o last, y supongo que te saldría el resultado que esperas, es decir, la hora de entrada de cada día.

Respecto a la función que publiqué, le falta un parámetro, que es el campo a sumar. Supongo que es lo que está mal.
Si no recuerdo mal, el procedimiento genera una sentencia sql. Haz pruebas y pon los parámetros de entrada y la sentencia que genera en cada caso, para que pueda analizarlas. A ver si puedo ponerte algo de luz en el asunto.

Estamos en contacto.

Saludos
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
Responder Con Cita
  #12  
Antiguo 20-09-2012
MDante MDante is offline
Registrado
 
Registrado: sep 2012
Posts: 3
Poder: 0
MDante Va por buen camino
Primero que nada, gracias por tomarte la molestia de responder , en efecto el código que tu nos ofreces funciona perfectamente cuando hay campos a sumar lo único que me faltaba hacer era colocar los campos entre apostrofes , sin embargo yo no tengo ningún campo a sumar, aunque de todas formas me funciona de maravilla para otras cosas, por otra parte por supuesto que se que el valor devuelto de count es un valor nonull y debido a mi inexperiencia esperaba encontrar alguna sentencia en alguna parte de Internet que me devolviera el campo que necesito, que son las fechas en columnas, sin embargo también funciona como lista de asistencia, después de todo ese era el proyecto que tenia por encargo, desplegar en una lista las asistencias de los alumnos por cada día del mes, y ya que devuelve valores nonull, en las fechas donde no hay asistencia devuelve un cero y donde hay asistencia devuelve un hermoso 1 , me habría gustado mas que apareciera la hora por cada día, pero ya que no logro hacer eso ni con transform y pivot en MS SQL llegue a la conclusión de que mejor voy a desplegar la información reacomodandola mediante uso de matrices y después enviarlos a un dataset o un datatable ya que yo uso C# soy nuevo en rad studio y mi versión caducará pronto pero me encanto trabajar en rad studio cuando logre hacerlo prometo publicar un prototipo para quien quiera usarlo tanto en C# como en delphi.


Saludos y hasta pronto
Responder Con Cita
  #13  
Antiguo 20-09-2012
MDante MDante is offline
Registrado
 
Registrado: sep 2012
Posts: 3
Poder: 0
MDante Va por buen camino
Por cierto olvide poner el query que me devuelve unos y ceros jeje


Código Delphi [-]
select distinct 
    clavealumno as clave,
    count( registroentrada) as entrada,
    count( case when cast (entrada as date) = '10/01/2010' then 0 end ) as dia1,
    count( case when cast (entrada as date) = '10/02/2010' then 0 end ) as dia2,
    count( case when cast (entrada as date) = '10/03/2010' then 0 end ) as dia3,
    count( case when cast (entrada as date) = '10/04/2010' then 0 end ) as dia4,
    count( case when cast (entrada as date) = '10/05/2010' then 0 end ) as dia5,
    count( case when cast (entrada as date) = '10/06/2010' then 0 end ) as dia6,
    count( case when cast (entrada as date) = '10/07/2010' then 0 end ) as dia7,
    count( case when cast (entrada as date) = '10/08/2010' then 0 end ) as dia8,
    count( case when cast (entrada as date) = '10/09/2010' then 0 end ) as dia9,
    count( case when cast (entrada as date) = '10/10/2010' then 0 end ) as dia10,
    count( case when cast (entrada as date) = '10/11/2010' then 0 end ) as dia11,
    count( case when cast (entrada as date) = '10/12/2010' then 0 end ) as dia12,
    count( case when cast (entrada as date) = '10/13/2010' then 0 end ) as dia13,
    count( case when cast (entrada as date) = '10/14/2010' then 0 end ) as dia14,
    count( case when cast (entrada as date) = '10/15/2010' then 0 end ) as dia15
from asistencia
where 
   (
      (clavealumno < 400)
   and 
      (registroentrada between cast('10/1/2010'as date) and cast('10/15/2010' as date))
   )
group by clavealumno
order by 1
Responder Con Cita
  #14  
Antiguo 20-09-2012
Avatar de fjcg02
[fjcg02] fjcg02 is offline
Miembro Premium
 
Registrado: dic 2003
Ubicación: Zamudio
Posts: 1.369
Poder: 15
fjcg02 Va camino a la fama
A ver, hombre de poca fe...

Vas a probar con esto, que significa básicamente lo siguiente...

Cogeme las fechas de entrada de los alumnos y haces esto
- si es el día uno, coges la hora y la conviertes a caracteres. Si no es día uno te quedas con el valor '00:00'. Te quedas con el valor más alto ( es decir, el que tenga un valor ).
- Así para cada día.

Además, me lo agrupas por alumno.

Código SQL [-]
select clavealumno as clave,
 max( case when extract(day from entrada) = 1 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 1" ,
 max( case when extract(day from entrada) = 2 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 2" ,
 max( case when extract(day from entrada) = 3 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 3" ,
 max( case when extract(day from entrada) = 4 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 4" ,
 max( case when extract(day from entrada) = 5 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 5" ,
 max( case when extract(day from entrada) = 6 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 6" ,
 max( case when extract(day from entrada) = 7 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 7" ,
 max( case when extract(day from entrada) = 8 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 8" ,
 max( case when extract(day from entrada) = 9 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 9" ,
 max( case when extract(day from entrada) = 10 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 10" ,
 max( case when extract(day from entrada) = 11 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 11" ,
 max( case when extract(day from entrada) = 12 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 12" ,
 max( case when extract(day from entrada) = 13 then cast(cast(entrada as time) as varchar(25)) else '00:00' end) as "DIA 13"

 from asistencia
where 
   (
      (clavealumno < 400)
   and 
      (registroentrada between cast('10/1/2010'as date) and cast('10/15/2010' as date))
   )
group by clavealumno

Lo pruebas, si funciona perfecto, pero te dejo de deberes que lo estudies y lo entiendas.

Nos informas, majete.

Saludos
PD: A ver si te ganas esa buena nota, aunque sea tarde.
__________________
Cuando los grillos cantan, es que es de noche - viejo proverbio chino -
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Referencias Cruzadas GustavoCruz Firebird e Interbase 7 02-12-2008 23:14:25
Consulta de referencias cruzadas victork_py Firebird e Interbase 5 18-06-2007 16:44:14
Consulta de referencias cruzadas jzginez Firebird e Interbase 2 30-07-2004 04:38:25
consultas de referencias cruzadas Manuela SQL 2 31-08-2003 22:24:55
Consultas de referencias cruzadas Manuela Impresión 0 19-08-2003 21:50:43


La franja horaria es GMT +2. Ahora son las 06:44:37.


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