Realizar una consulta, usando datos de otra consulta

Me gustaría hacer una pregunta y a ver si me podéis ayudar. He estado mirando por Internet y no consigo encontrar una respuesta que me ayude a plantear lo que quiero hacer. Antes de nada decir que nos soy un experto solo alguien autodidacta. Por eso requiero de vuestra ayuda.

Mi pregunta es esta:

Tengo una tabla llamada usuarios, ella existen los campos IDusuario y Usuario . Estos usuarios se eliminan una vez ya no venden.

Tengo otra tabla donde están las ventas de esos usuarios, llamada contratos, donde están los campos IDusuario (este campo guarda el mismo ID que el de la tabla usuarios), Tipo (los datos que se guardan son : moto y coche).

La idea es que me gustaría hacer es mostrar un listado donde aparezca los Usuario que estén en la activos en ese momento en la tabla usuarios, hasta ahí todo fácil. Me gustaría coger esos usuarios y usarlos para filtrar la tabla contratos y así mostrar la cantidad de motos o coche que ha vendido ese usuario.

Ejemplo de lo que me gustaría hacer:

IDusuario, Nombre, Moto(Cantidad) Coche(Cantidad)

12 Manolo 2 1

13 Paco 4 3

Etc

No sé si me he explicado correctamente, si necesitáis cualquier información o aclaración.

1 Respuesta

Respuesta
1

Te sugiero la estrutura siguiente:

Tabla Contrato:
IDusuario | Nombre |  Tipo  | Cantidad
-------------------------------------
    12    | Manolo |  Moto  |   2
-------------------------------------
    12    | Manolo |  coche |   1
-------------------------------------
    13    | Paco   |  Moto  |   4  
-------------------------------------
    13    | Paco   |  coche |   3  

Si vas a filtrar usa la cláusula WHERE.
Por ejemplo: 

SELECT * FROM tb_contrato WHERE IDusuario='12';

Eso me mostraría:

IDusuario | Nombre |  Tipo  | Cantidad
-------------------------------------
    12    | Manolo |  Moto  |   2
-------------------------------------
    12 | Manolo | coche | 1

Si quieres que te muestre la cantidad total, usa COUNT (en SQL Server), debes agrupar con la cláusula GROUP BY.
Te podría ayudar con más precisión si me das más datos, por ejemplo, el esquema de tu base de datos, y sobre todo en que sistema de gestión de base de datos estás trabajando.

Gracias.

Eso sería lo más lógico.  Pero el tema está que la tablas tienen que ir por separado. Ya que la tabla usuarios se usa para el acceso a la base de datos. Por eso quiero usarla para sacar la lista por los usuarios activos en la tabla de contratos.

¿Se podría hacer?

Por supuesto que las tablas van por separado. La tabla de contratos es dependiente de la de usuarios. Por eso, si me muestras un diagrama con tu base de datos y en qué gestor (SQL Server, MySQL, PostgueSQL, etc) los estás haciendo, sería más sencillo ayudarte.

La tabla contratos la nutrimos de un excel, que volcamos diariamente a la base de datos.

Y la tabla usuarios la que usamos para el acceso.

Estoy usando MySQL para gestionarlo uso wampserver.

los campos en común entre las dos tablas son:  en la tabla usuarios-nuusuario y de la tabla contratos-Agente. Lo marco en rojo en el diagrama.

Los campos IdentificadorAM, no pueden ser modificados por uno son aportados desde el excel y es la referencia del contrato. Y idUsuario se lo genera la base de datos.

Cualquier información que necesites más dímelo. No soy un experto por eso seguro que ves algunas cosas que podrían estar mejor hechas pero... voy aprendiendo! jejeje

Muchas gracias por la ayuda que me estas prestando!!

Entiendo, no te preocupes, no es difícil, sólo práctica y lectura de documentación SQL.

Tienes que relacionar tus tablas. Comprendo que el volcado de datos sea desde Excel, pero centrémonos sólo en la base de datos.

Para relacionar una tabla con otra se utiliza una Llave Foránea (Foreign Key o FK), que lo que hace es crear un enlace a través de la llave primaria (Primary Key o PK) de la tabla independiente (Usuario en tu caso) con un atributo de la tabla dependiente (Contrato).

Hay ciertos criterios que debes seguir. Por ejemplo, si tu llave primaria de tu tabla independiente es idUsuario, y es del tipo INT, entonces, en tu tabla dependiente debe haber un atributo homólogo a éste para que pueda haber el enlace; es decir, debe haber un atributo del tipo INT. Así como se ve en la siguiente imagen.

El atributo idUsuario (PK) y C_idUsuario (FK) son tales, así que el enlace se realiza, y no da problemas al crearlo al escribir el script:

Un CONSTRAINT es una restricción, un FK es una restricción, y hay distintas formas de crearla. Como ves en la imagen anterior, usualmente así es como yo la creo.

CONSTRAINT [NombredeFK] FOREING KEY (AtributoDeLlegada) REFERENCES [TablaIndependiente] (AtributoDeSalida);

Ahora, es necesario que tu atributo de llegada de enlace (C_idUsuario, en la imagen) sea igual al tipo de la PK de tu tabla independiente. No puedes referenciarlo a otro atributo que no sea una PK. Por lo tanto, el enlace no se puede crear si hago esto:

CONTRAINT FK_UsuarioContrato FOREIGN KEY (Agente) REFERENCES usuario (nuusuario); 

Esto dará conflictos por las siguientes razones:

  1. El atributo de llegada (Agente), es un VARCHAR(12) y el de salida o de enlace (nuusuario) es un VARCHAR(45). ¿Qué tal si llega una cadena de tamaño 20 a tu tabla contrato que sólo acepta 12 como máximo? Sería un dolor de cabeza si estás en producción.
  2. El atributo de nuusuario no es la PK de tu tabla independiente, por lo tanto, el CONTRAINT no se creará y te marcará error fatal, es decir, que interrumpe la ejecución del script. Debe ser la PK de tu tabla independiente para poder crear el enlace.

Entonces, en tu caso, o bien es tu PK el atributo idUsuario o lo es nuusuario.

Si es el segundo, quedaría algo así:

Ves, son tales. Y el enlace está hecho sin problemas en el diagrama. En el script se vería algo así:

Para poder crear el CONTRAINT tuve que cambiar la PK en la tabla Usuario.

Espero hayas podido comprender. Debes darte tiempo y leer la documentación de SQL o ver tutoriales. Practica un poco ello, verás que es cuestión de estar dándole una y otra vez. Otra cosa, usa de la mejor forma posible los VARCHAR y CHAR; busca sobre sus diferencias y como usarlas, por si no lo sabes aún.

Si quieres documentación menos formal y ligera, aquí una web con buena info sobre SQL, espero te sirva, a mí me sirvió en mis repasos.

Errata: No puedes referenciarlo a otro atributo que no sea una PORQUE u otra clave candidata.

Errata2: No puedes referenciarlo a otro atributo que no sea una PK* u otra clave candidata. n.n'

voy a ponerme con ello, para poner en practica lo que me has explicado, en breve te digo algo muchas gracias!

Por nada, es un gusto. :)

Buenas tardes,

He estado desarrollando todo lo que me has explicado.

He cambiado el PK de usuarios como has indicado.

He creado el FK usando tu modelo.

Y todo ha quedo relacionado así:

Cuando quise actualizar la tabla contratos con el excel me dio error.

#1452 - Cannot add or update a child row: a foreign key constraint fails (`jo`.`contratos`, CONSTRAINT `FK_UsuarioContrato` FOREIGN KEY (`C_nuusuario`) REFERENCES `usuario` (`nuusuario`))

Y hasta he podido hacer. Por que ocurre, esto?

¿Qué es ese "jo" allí?
Ese error podría ser porque podrías estar volcando datos de la tabla dependiente (Contrato) antes que la de la tabla independiente (Usuario). Primero es la tabla Usuario, pues primero debe existir los usuarios en la base de datos para que puedan referenciarse a un contrato.
Si no es por eso, hay algo mal en el CONSTRAINT.

Buenas, 

Jo es el nombre de la base de datos donde están las tablas. 

Cuando cambié la PK de usuarios. A nuusuarios tb la puse INT. Ya que siempre lleva valor numérico. Y depuesto de estos cambios volví a cargar todos los usuarios.

 En la tabla contratos tb puse a Agente INT. Pues también es numérico.  Tenían VARCHAR pero estaba mal definido.

Y esta hice lo mismo elimine la tabla la cree con los cambios y al subir los datos usando el csv  salta el error que te.puse

Debes verificar todos tus tipos de dato para que no haya ninguna discordancia, además de definir correctamente tu llave foránea, ya que el problema es ese. Haré pruebas con excel a ver si me va así.

¡Gracias! Ya me ha salido! Gracias a tu guía y consejos! !! Te lo agradezcomento mucho!!! ;-)

Me da gusto que encontraras solución.
¿Cuál era el fallo?
No olvides tener claro los conceptos de las llaves, que son importantes, básicos.
Por nada, fue un gusto ayudar.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas