Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > SQL
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 18-09-2008
Avatar de tcp_ip_es
tcp_ip_es tcp_ip_es is offline
No confirmado
 
Registrado: ago 2003
Ubicación: Madrid
Posts: 635
Poder: 0
tcp_ip_es Va por buen camino
Relación imposible

Os cuento, estoy empezando a hacer un aplicación, todavía no he diseñado la BD, pero como siempre pienso en el futuro y llego a plantearme dudas.. bueno al hecho. Tengo que hacer una BD de contratos (en otro hilo ya he comentado otras dudillas que han sido más o menos resueltas ) joe mira que me enrrollo... bueno pues en esa BD tengo las siguientes tablas:

Contratos
idcontrato
FechaFirma
FechaEntradaVigor
Objeto
IdTipoContrato
etc..

Partes
idPartes
IdContrato
IdEmpresa
Clase
Responsable

Tengo más tablas pero mi pregunta es sobre estas dos; la tabla partes se refiere a las Partes que tiene el contrato, la empresa que contrata y las n empresas que son contratadas, el campo clase definirá si es contratante o contratista. Esta tabla la relaciono con contratos por el campo idcontrato de manera: Contratos ->1-n->Partes

Bueno la duda el usuario lo que quiere es que a la hora de ver un informe de contratos o en dbgrid ver lo siguiente:

idcontrato parte1 parte2 parten... FechaFirma FechaEntradaVigor Objeto IdTipoContrato
1 empresaA EmpresaB EmpresaN 01/02/08 01/02/08 Limpieza 3
2 empresaB EmpresaD EmpresaN 03/05/08 03/05/08 Seguridad 3
3 empresaA EmpresaY EmpresaN 17/07/08 17/07/08 Informatica 3

y eso con sql puessss no se me ocurre como sacárselo....

Ellos (Los usuarios ) me dan la posibilidad de limitar las partes a 4 con lo que podría meter cuatro campos en la tabla contratos, pero luego a la hora de la búsqueda sería un poco rollo preguntar siempre por cuatro campos :
Código SQL [-]
where (parte1=x) or (parte2=x) or (parte3=x) or (parte4=x)

Bueno pues esa es mi pregunta, no se si debería ir aqui el hilo o en Conexión de BD, esto es una mezca de Diseño de BD y SQL

Última edición por tcp_ip_es fecha: 18-09-2008 a las 09:59:39.
Responder Con Cita
  #2  
Antiguo 18-09-2008
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Lo que puedes utilizar es una tabla de "relaciones". Por ejemplo:
Código:
REL_CONTRATO_PARTE
  id_contrato
  id_parte
De esta forma, para saber los partes de un contrato:
Código SQL [-]
SELECT partes.*
FROM partes, contratos, rel_contrato_parte
WHERE contrato.id = x
  AND rel_contrato_parte.id_contrato = contratos.id
  AND partes.id = rel_contrato_parte.id_parte;
Como ves, partes y contratos se relacionan a través de esa tabla "intermedia". Además, si en el futuro hay más de cuatro partes por contrato no tienes que cambiar el diseño de la base de datos.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #3  
Antiguo 18-09-2008
Avatar de tcp_ip_es
tcp_ip_es tcp_ip_es is offline
No confirmado
 
Registrado: ago 2003
Ubicación: Madrid
Posts: 635
Poder: 0
tcp_ip_es Va por buen camino
Pero de la manera que he expuesto yo tambien puede poner cuantas partes quiera, lo único que no me salen como quiere el usuario que salgan, con lo que me pones tu tambien pasa lo mismo. de hecho es lo mismo que he expuesto yo... mi tabla partes es como la tabla de relacion que me pones tu, yo relaciono idcontrato y un idempresa.....

lo que quiero:

idcontrato parte1 parte2 parten... FechaFirma FechaEntradaVigor Objeto IdTipoContrato
1 empresaA EmpresaB EmpresaN 01/02/08 01/02/08 Limpieza 3
2 empresaB EmpresaD EmpresaN 03/05/08 03/05/08 Seguridad 3
3 empresaA EmpresaY EmpresaN 17/07/08 17/07/08 Informatica 3

lo que me has puesto tu:

parte1 contrato1 FechaFirma1 FechaEntradaVigor1 Objeto1
parte2 contrato1 FechaFirma1 FechaEntradaVigor1 Objeto1

lo que quiero es que las partes salgan por columnas y los contratos 1 a 1 por filas... creo que realmente es imposible hacer esto pero si tenéis alguna solución....

Última edición por tcp_ip_es fecha: 18-09-2008 a las 11:21:19.
Responder Con Cita
  #4  
Antiguo 18-09-2008
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Esta clase de problemas (mostrar horizontalmente una tabla) la soluciono con procedimientos almacenados o con tamblas temporales.

Si es con tablas temporales, al crear el Form que contiene el grid o al lanzar el listado, relleno esta tabla. Dependiendo del tiempo que esté abierto este Form, también le pongo un botón para refrescar datos, que vuelve a rellenar la tabla temporal.
Responder Con Cita
  #5  
Antiguo 18-09-2008
[coso] coso is offline
Miembro Premium
 
Registrado: may 2008
Ubicación: Girona
Posts: 1.678
Poder: 0
coso Va por buen camino
Hola, imposible no pero bastante elaborado si. Creo q como te dice ñuño una tabla intermedia, o un rediseño te lo optimizaria bastante. Lo q yo tenia pensado para solucionarlo

Código SQL [-]
select (select idcontratos from contratos) as idcontratos,
         (select first(idparte) from partes where idcontratos = contratos.idcontratos) as id1, 
         (select first(idparte) from partes where idcontratos = contratos.idcontratos and idparte <> id1) as id2, 
         (select first(idparte) from partes where idcontratos = contratos.idcontratos and idparte <> id1 and idparte <> id2) as id3, 
         (select first(idparte) from partes where idcontratos = contratos.idcontratos and idparte <> id1 and idparte <> id2 and idparte <> id3) as id4, 
         (select empresa from partes where idparte = id1) as empresa1, 
         (select empresa from partes where idparte = id2) as empresa2, 
         (select empresa from partes where idparte = id3) as empresa3, 
         (select empresa from partes where idparte = id4) as empresa4, 
         fechaentrada ...

luego no mostrando los campos id1,id2,id3,id4. Seria mas elegante recoger todos los campos 'idparte where idcontratos = contratos.idcontratos' y colocarlos en un 'array', para que luego mediante un where in [...] seleccionar las empresas, o bien mediante un bucle usando for... Desconozco bien bien como funcionan los bucles y arrays en sql, por lo que no pongo nada mas, pero es probable que se pueda hacer asi. Saludos.

Última edición por coso fecha: 18-09-2008 a las 11:55:34.
Responder Con Cita
  #6  
Antiguo 18-09-2008
Avatar de tcp_ip_es
tcp_ip_es tcp_ip_es is offline
No confirmado
 
Registrado: ago 2003
Ubicación: Madrid
Posts: 635
Poder: 0
tcp_ip_es Va por buen camino
je je coso lo que me has puesto lo había pensado también pero es muy engorroso a parte no te aseguras todas las partes del contrato recuerda que son n partes no solo cuatro si son solo cuatro al final optaré por ponerlas en la misma tabla contratos. En cuanto al rediseño estoy abierto a que me planteeis otra solución todavía no he empezado a crear la BD simplemente es la idea inicial.

Lo que dice duilioisola esta bien pero no se mucho sobre procedimientos almacenados en MySQL y como pasarle valores desde delphi. Se supone que lo que tendría que hacer es crear una tabla temporal donde meta los contratos 1 a 1 y mediante un for o algo asi vaya creando tantos campos como partes tenga el contrato??? pero asi en una misma tabla unos contratos tendrán más campos que otros ??? ahhhhh esto no puede ser...
Responder Con Cita
  #7  
Antiguo 18-09-2008
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Personalmente creo que no es una buena organización para mostrar datos (salvo utilizando Pivot Tables/Tablas dinámicas).
* Son muy ineficientes a la hora de calcularlas frente a otras posibilidades similares.
* Suelen ser incompletas (salvo casos particulares); En tu caso el cliente te ha limitado a 4. **NOTA**
* En tu caso además estás perdiendo información de las partes; Todo lo que no es la empresa.
* Si mencionar las complicaciones que ya han comentado a la hora de ordenar, filtrar,...

Si no consigues cambiar la opinión del cliente para que se "conforme" con un Maestro detalle o un agrupado, mi recomendación es que trabajes sobre tablas temporales utilizando Stored Procedures y luego muestres los datos.


_________________________________________
**NOTA**: Si me guaradara un euro cada vez que me pide algo y me dicen; "Con esto vale, lo otro no va a hacer falta" y un mes después me piden lo que nunca iba a ser necesario (porque ahora se ha vuelto imprescindible) sería rico.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #8  
Antiguo 18-09-2008
[coso] coso is offline
Miembro Premium
 
Registrado: may 2008
Ubicación: Girona
Posts: 1.678
Poder: 0
coso Va por buen camino
si lo es, si . Es una relacion maestro detalle, con el numero de detalles variables, por lo que tendras que usar varias tablas.
Responder Con Cita
  #9  
Antiguo 18-09-2008
Avatar de tcp_ip_es
tcp_ip_es tcp_ip_es is offline
No confirmado
 
Registrado: ago 2003
Ubicación: Madrid
Posts: 635
Poder: 0
tcp_ip_es Va por buen camino
Cita:
Empezado por Neftali
**NOTA**: Si me guaradara un euro cada vez que me pide algo y me dicen; "Con esto vale, lo otro no va a hacer falta" y un mes después me piden lo que nunca iba a ser necesario (porque ahora se ha vuelto imprescindible) sería rico.
je je ¿Por que te crees que lo quiero dejar ilimitado? porque se que al final donde dije x ahora es x+1.

cuando dices:

Cita:
Empezado por Neftali
Personalmente creo que no es una buena organización para mostrar datos (salvo utilizando Pivot Tables/Tablas dinámicas).
a que organización te refieres??? a la de meter las partes como campos de contratos??

Cita:
Empezado por Neftali
En tu caso además estás perdiendo información de las partes; Todo lo que no es la empresa.
si lo hago como he puesto en el primer post no pierdo, lo que pasa es que me faltaría una tabla empresas, no la he puesto para no liar, la tabla partes iría relacionada con la tabla empresas 1 - N, y en esta tabla estaría el nombre, el cif, la dirección... etc....
Responder Con Cita
  #10  
Antiguo 18-09-2008
[coso] coso is offline
Miembro Premium
 
Registrado: may 2008
Ubicación: Girona
Posts: 1.678
Poder: 0
coso Va por buen camino
Aunque, si en contratos tansolo necesitas el nombre de las empresas de las partes...¿no te iria mejor ponerlas todas en un campo string o memo tansolo? (separadas por comas, o bien por #13). Para los filtros y para todo, al menos de la tabla contratos, te lo optimizaria bastante, y seria mas leible desde una dbgrid por ejemplo, que no tener un numero variable de columnas.

PD: incluso guardando sus idpartes correspondientes en otro campo oculto. Es un poco chapucilla si, pero funcionaria. Si no, deberas buscar el contrato con mayor numero de partes, e ir rellenando la consulta 'contratos' con tantos campos como le falten, incluyendo 'manualmente' (con lo de id<> a los que ya se tienen) por cada idcontrato...

Última edición por coso fecha: 18-09-2008 a las 12:43:36.
Responder Con Cita
  #11  
Antiguo 18-09-2008
Avatar de tcp_ip_es
tcp_ip_es tcp_ip_es is offline
No confirmado
 
Registrado: ago 2003
Ubicación: Madrid
Posts: 635
Poder: 0
tcp_ip_es Va por buen camino
Es una idea muy buena, es decir tu lo que harías es mantener la relacción maestro detalle (Contratos->Partes) y a parte crearías un campo memo en contrato con todas las partes asociadas uhmmmm esta bien lo único que tendría que tener actualizado ese campo siempre, es decir si hay una modificación en alguna de las partes tendría que cambiarlo en ese memo, y si se borra una parte, tambien la borraría en el memo.... me gusta la idea...
Responder Con Cita
  #12  
Antiguo 18-09-2008
[coso] coso is offline
Miembro Premium
 
Registrado: may 2008
Ubicación: Girona
Posts: 1.678
Poder: 0
coso Va por buen camino
ya diras algo saludos
Responder Con Cita
  #13  
Antiguo 18-09-2008
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Yo comenzaría preguntándole al cliente qué espera ver en todos los recuadros en blanco que quedarán. Porque donde un contrato esté asociado a diez empresas y los restantes sólo a dos o tres, va a haber muchos huecos sin sentido.

Tampoco veo porqué meter una tabla extra, no se trata de una relación n-n sino de una relación 1-n, cosa que ya está contemplada en el diseño.

Vistas las cosas, creo que la idea de coso es lo mejor que se puede hacer, aunque podrías hacerles un prototipo mostrándoles un maestro-detalle en forma, quien quita y los convences.

// Saludos
Responder Con Cita
  #14  
Antiguo 18-09-2008
Avatar de tcp_ip_es
tcp_ip_es tcp_ip_es is offline
No confirmado
 
Registrado: ago 2003
Ubicación: Madrid
Posts: 635
Poder: 0
tcp_ip_es Va por buen camino
Entonces mi idea del principio + la aportación de incluir un campo texto con las partes (aportacion coso) es correcta no??

a que te refieres cuando dices...
Cita:
Empezado por Roman
aunque podrías hacerles un prototipo mostrándoles un maestro-detalle en forma, quien quita y los convences.
Os dejo un link a una imagen del diseño fijaros en las tablas Contratos, PartesContrato y empresas ahi es donde esta el problema
Bueno realmente me pasa lo mismo con escrituras y apoderados, con lo cual tanto en contratos como en escrituras he añadido un campo, que será memo, para las partes y los apoderados.


Última edición por tcp_ip_es fecha: 18-09-2008 a las 16:45:50.
Responder Con Cita
  #15  
Antiguo 18-09-2008
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por tcp_ip_es Ver Mensaje
a que te refieres cuando dices...
Pues a poner un segundo dbgrid que muestre las distintas partes conforme nos movemos por el dbgrid de los contratos.

Cita:
Empezado por tcp_ip_es Ver Mensaje
Os dejo un link a una imagen del diseño fijaros en las tablas Contratos, PartesContrato y empresas ahi es donde esta el problema
Has puesto el enlace a la vista en miniatura. Comprenderás que de ahí no es posible hacerse ninguna idea

// Saludos
Responder Con Cita
  #16  
Antiguo 18-09-2008
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.556
Poder: 25
egostar Va camino a la fama
Hola

Cita:
Quien quita = Puede ser, Tal vez, a lo mejor


Salud OS
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #17  
Antiguo 18-09-2008
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
¡Ah vaya! Ni siquiera me había fijado en la pregunta exacta de Tony . Gracias por la aclaración Eliseo, quien quita y se acostumbran a nuestras expresiones .

// Saludos
Responder Con Cita
  #18  
Antiguo 18-09-2008
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.556
Poder: 25
egostar Va camino a la fama
Cita:
Empezado por roman Ver Mensaje
¡Ah vaya! Ni siquiera me había fijado en la pregunta exacta de Tony . Gracias por la aclaración Eliseo, quien quita y se acostumbran a nuestras expresiones .

// Saludos
Chance y si

Salud OS
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #19  
Antiguo 19-09-2008
Avatar de tcp_ip_es
tcp_ip_es tcp_ip_es is offline
No confirmado
 
Registrado: ago 2003
Ubicación: Madrid
Posts: 635
Poder: 0
tcp_ip_es Va por buen camino
Edite la url del link, espero que ahora se vea correctamente.

Efectivamente quien quita que no entendiese la frase hecha "quien quita" . Aqui vamos entendiendo ya toda vuestra jerga, somos minoría

Lo que dices sobre el maestro detalle con los dos dbgrid ya estaba en mi cabeza, si lo que pasa es a la hora de los informes, pero bueno como bien dices...

Cita:
Empezado por Roman
Yo comenzaría preguntándole al cliente qué espera ver en todos los recuadros en blanco que quedarán. Porque donde un contrato esté asociado a diez empresas y los restantes sólo a dos o tres, va a haber muchos huecos sin sentido.
Responder Con Cita
  #20  
Antiguo 19-09-2008
Nelet Nelet is offline
Miembro
 
Registrado: may 2003
Ubicación: Picassent - Valencia
Posts: 95
Poder: 21
Nelet Va por buen camino
Ahí va una idea:

Antes de presentar el dbgrid o el informe podrias calcular el máximo número de partes que vas a obtener.

Una vez obtenido el número de columnas que vas a necesitar solo tendrías que montar una query añadiendo las columnas necesarias.

Por ejemplo, esto funcionaria en sqlserver. En mysql creo que es parecido,

Código SQL [-]
SELECT COUNT(ID_PARTES) FROM PARTES_CONTRATO WHERE ID_CONTRATO IN("LISTA DE CONTRATOS")

Código SQL [-]
select id_contrato, 
case when id_parte=1 then ID_EMPRESA else "" end,
case when id_parte=2 then ID_EMPRESA else "" end,
.....
case when id_parte=numeropartes then ID_EMPRESA else "" end,
FechaFirma, FechaEntradaVigor, Objeto, IdTipoContrato
from contratos a 
inner join PartesContrato b on
a.id_contrato=b.id_contrato
where a.id_contrato in(..lista de contratos..)

Esto lo puedes ir formando en un query y así obtener de forma dinamica las columnas que necesites. De esta forma el contrato con el máximo numero de partes tendría todas las columnas rellenas y los restantes columnas en blanco donde no existiese el id_parte.

Todo esto se puede hacer siempre y cuando el ID_PARTE sea secuencial.

Espero haberte ayudado en algo.
__________________
_____________________________________
And follow me to where the real fun is

Última edición por Nelet fecha: 19-09-2008 a las 11:54:04.
Responder Con Cita
Respuesta



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
¿Mision imposible? Alvarobc Conexión con bases de datos 8 26-04-2007 05:40:34
Es imposible un lector de DVD???? gandalf_27 Varios 2 15-06-2006 16:07:40
Es Esto imposible? jam888 Varios 1 28-04-2005 01:02:35
imposible con interbase jomaho Firebird e Interbase 1 10-05-2003 11:44:14


La franja horaria es GMT +2. Ahora son las 09:49:33.


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
Copyright 1996-2007 Club Delphi