Ver Mensaje Individual
  #5 (permalink)  
Antiguo 13/03/2011, 05:58
Avatar de gnzsoloyo
gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: consulta en BD relacional

Código MySQL:
Ver original
  1. SELECT cédula, nom1, ape1, ahocta.ctaahor
  2. FROM cliente NATURAL JOIN ahocta
  3. WHERE idaho=1;
Está mal planteada...
Tal y como lo describes, la tabla Cliente no se relaciona directamente con Ahocta, sino por medio de otra tabla (tipocta), por lo que la sentencia en esas condiciones genera un producto cartesiano (situación donde cada registro es la combinacion de cada registro de la primera tabla con cada registro de la segunda), en esas condiciones, es lógico que haya al menos dos combinaciones de diferentes usuarios que cumplan la condición.

El problema base pareciera ser que el modelo en sí está mal planeado.

Si tienes un usuario que puede tener más de un tipo de cuenta, en realidad tienes tres tablas o cuatro, pero de otra forma.

Caso 1: Los tipos de cuenta distintos sólo se diferencian por nombre y valores de sus atributos, pero el conjunto de datos de cada cuenta tiene la misma cantidad de atributos.

Cliente(cedula, nom1, nom2, ape1, ape2, saldo)
Cuenta(cuenta_id, descripcion_cta, otros datos)
Cliente_Cuenta(cedula, cuenta_id)

Consulta:
Código MySQL:
Ver original
  1. SELECT cedula, nom1, ape1, cuenta_id, descripcion  
  2. FROM cliente C INNER JOIN cliente_cuenta CC ON C.cedula = CC.cedula
  3. INNER JOIN cuenta CT ON CC.cuenta_id = CT.cuenta:id
  4. WHERE CC.cuenta_ic=1;

Caso 2: Los tipos de cuenta poseen datos de diferente clase, por lo que o no tienen iguales dominios (clases de datos representados) o no son iguales las cantidades de atributos. Se genera una jerarquía con subtipos, siendo Cuenta la tabla principal y las hijas CuentaCorriente y CajAhorros.

Cliente(cedula, nom1, nom2, ape1, ape2, saldo)
Cuenta(cuenta_id)
CajaAhorros(cuenta_id, descripcion_cta, otros datos)
CuentaCorriente(cuenta_id, descripcion_cta, otros datos)
Cliente_Cuenta(cedula, cuenta_id)

Este caso desde el punto de vista es más eficiente y preciso, pero hace las consultas algo complejas, pudiendo tener que resolverse en más de una consulta, y debe hacerse en parte programáticamente (a través de la aplicación), pero en definitiva es el modo usado en los sistemas de este tipo.
El login de este tipo lo primero que hace es buscar todos los tipos de cuenta que el usuario posee y muestra las opciones posibles. Según cual opción sea, variará la tercera tabla consultada y los datos obtenidosrepresentados, pero la consulta base es la misma
Código MySQL:
Ver original
  1. SELECT cedula, nom1, ape1, cuenta_id, descripcion  [, otros datos...]
  2.     cliente C
  3.     INNER JOIN
  4.     cliente_cuenta CC ON C.cedula = CC.cedula
  5.     INNER JOIN
  6.     [tabla de la cuenta según tipo] CT ON CC.cuenta_id = CT.cuenta:id
  7. WHERE CC.cuenta_ic=1;

El modelo como tu lo planteaste exigiría que tengas dos tablas que mantengan la relación N:N:N de clientes, cuentas y tipo de cuenta, porque no puedes definir diferentes referencias para la misma FK, sino exige hacer una tabla donde pones ambas (lo que tu haces), pero eso también haría que el usuario tenga forzosamente ambos tipos si o sí.

Un detalle a tener en cuenta: NATURAL JOIN en SQL no es lo mismo que Junta Natural en el álgebra relacional, o al menos no lo es en MySQL. No los confundas.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)