SQL - CONSULTA SQL

 
Vista:
sin imagen de perfil
Val: 10
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

CONSULTA SQL

Publicado por Guille (5 intervenciones) el 24/11/2017 16:16:28
Hola, estoy haciendo una consulta que consite en dado un id de un cliente y un mes, consultar las ventas de ese cliente en ese mes y devolver el producto que más ha comprado, tengo tabla Ventas que contiene la fecha y el id del cliente, tengo tabla registrado que contiene el id de la venta, unidades, e id del producto, y tengo la tabla productos con sus datos, hago lo siguiente:

SELECT `id`,`nombre`,`precio`,`unidades`,`activo` FROM producto AS Productos JOIN (SELECT *, MAX(Suma) "Maximo" FROM (SELECT `producto_id`, SUM(`unidades`) "Suma" FROM registrado AS Reg JOIN (SELECT `id` FROM `venta` WHERE MONTH(fecha) = 11 AND `cliente_id` = 4)AS Venta WHERE Reg.venta_id = Venta.id GROUP BY `producto_id`) AS tala GROUP BY `producto_id`) AS MaxSuma WHERE Productos.id = MaxSuma.producto_id AND MaxSuma.Suma = MaxSuma.Maximo

El problema es que no se como ponerlo según el máximo, en la que he puesto el maximo es segun id, luego te saca todos los productos y no funciona, si selecciono el maximo sin el group by solo me deja la primera fila de la tabla, y me quita el resto, podéis ayudarme?
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 806
Bronce
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

CONSULTA SQL

Publicado por leonardo_josue (1173 intervenciones) el 24/11/2017 17:01:05
Hola Guille:

Creo que estás abusando de las subconsultas, y tu consulta no se entiende... postea la estructura de tus tablas y pon algunos datos de ejemplo de cada una de ellas. A partir de esos datos, dinos entonces qué es lo que esperas como salida, Así será más factible que podamos ayudarte.

Dinos también con qué BD's estás trabajando, ya que cada uno de los motores tiene una sintaxis distinta. Puedo imaginar que se trata de MySQL, pero eso sólo Dios y tú lo saben. Ojo con eso para la próxima.

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 10
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

CONSULTA SQL

Publicado por Guillermo (5 intervenciones) el 24/11/2017 17:51:04
Hola Leo, gracias por contestar, uso mysql, te explico:

Esta es mi tabla ventas:

Sin-titulo2

Esta es la tabla registrado:

Sin-titulo3

Esta es mi tabla producto:

Sin-titulo6

Si hago esto

SELECT `id`,`nombre`,`precio`,`unidades`,`activo` FROM producto AS Productos JOIN (SELECT *, MAX(Suma) "Maximo" FROM (SELECT `producto_id`, SUM(`unidades`) "Suma" FROM registrado AS Reg JOIN (SELECT `id` FROM `venta` WHERE MONTH(fecha) = 11 AND `cliente_id` = 4)AS Venta WHERE Reg.venta_id = Venta.id GROUP BY `producto_id`) AS tala GROUP BY `producto_id`) AS MaxSuma WHERE Productos.id = MaxSuma.producto_id AND MaxSuma.Suma = MaxSuma.Maximo

Aparece:

Sin-titulo4

Si quito lo marcado en negrita sale:

Sin-titulo5

El id de cliente es 3, el mes es 11, las ventas que coinciden con eso son la 4 y la 6, los productos de esas ventas son el 2, el 4 y el 5, del 2 hay 5 unidades, del 4 sumando hay 20, y del 6 sumando hay 20, quiero que me muestre los datos del 4 y el 6 que son los que tienen las máximas unidades vendidas, si por ejemplo el 4 tuviese 10 y el 6 tuviese 20, solo quiero que me muestre el 6

Al hacer esto (SELECT *, MAX(Suma) "Maximo" FROM (SELECT `producto_id`, SUM(`unidades`) "Suma" FROM registrado AS Reg JOIN (SELECT `id` FROM `venta` WHERE MONTH(fecha) = 11 AND `cliente_id` = 4)AS Venta WHERE Reg.venta_id = Venta.id GROUP BY `producto_id`) AS tala )

me aparece:

Sin-titulo7

Lo que a mi me gustaría que saliese es

producto_id Suma Maximo
2----------------5--------20
4----------------20------20
6----------------20------20

o algo así, para luego poder comparar las sumas con el máximo y quedarme los productos que me interesan, el 4 y el 6 en este caso
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 806
Bronce
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

CONSULTA SQL

Publicado por leonardo_josue (1173 intervenciones) el 24/11/2017 20:51:34
Hola de Nuevo Guille:

Como te comenté, estás haciendo un mal uso de los JOIN's al hacer tantas subconsultas. te sugiero que le des una revisada a este tema en cualquier manual de SQL para que veas cómo utilizar mejor los JOIN's. Para el ejemplo, voy a tomar las tablas de ejemplo que nos pones:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
mysql> SELECT * FROM venta;
+------+--------------+------------+------------+
| id   | precio_total | fecha      | cliente_id |
+------+--------------+------------+------------+
|    1 |          200 | 2017-11-01 |          3 |
|    2 |          200 | 2017-11-02 |          3 |
|    3 |          200 | 2017-11-03 |          3 |
|    4 |           45 | 2017-11-15 |          4 |
|    5 |           45 | 2017-12-15 |          4 |
|    6 |           60 | 2017-11-13 |          4 |
+------+--------------+------------+------------+
6 rows in set (0.00 sec)
 
mysql> SELECT * FROM registrado;
+----------+--------------+-------------+----------+
| unidades | precio_venta | producto_id | venta_id |
+----------+--------------+-------------+----------+
|        3 |           99 |           2 |        1 |
|        3 |           99 |           3 |        1 |
|        3 |          200 |           2 |        2 |
|        5 |           45 |           2 |        4 |
|       10 |           89 |           4 |        4 |
|       10 |           12 |           5 |        4 |
|       10 |           12 |           4 |        6 |
|       10 |           12 |           5 |        6 |
+----------+--------------+-------------+----------+
8 rows in set (0.00 sec)

Entonces, para obtener la suma de los productos que a adquirido el cliente 4 en el mes de Noviembre, haces un INNER JOIN simple (Es decir, sin necesidad de hacer un SUB-SELECT:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> SELECT
    ->   registrado.producto_id,
    ->   SUM(registrado.unidades) suma
    -> FROM registrado
    -> INNER JOIN venta ON venta.id = registrado.venta_id
    -> WHERE
    ->   venta.cliente_id = 4 AND
    ->   MONTH(venta.fecha) = 11
    -> GROUP BY registrado.producto_id;
+-------------+------+
| producto_id | suma |
+-------------+------+
|           2 |    5 |
|           4 |   20 |
|           5 |   20 |
+-------------+------+
3 rows in set (0.00 sec)

Esta será tu consulta BASE. Ahora, para obtener la MAXIMA VENTA, puedes hacerlo de dos formas, una con un subselect, que es como lo estás haciendo y otra, más simple, es utilizando esta misma consulta, ordenando los registros de MAYOR A MENOR SUMA y obteniendo el primero, es decir, así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
mysql> SELECT
    ->   SUM(registrado.unidades) max_suma
    -> FROM registrado
    -> INNER JOIN venta ON venta.id = registrado.venta_id
    -> WHERE
    ->   venta.cliente_id = 4 AND
    ->   MONTH(venta.fecha) = 11
    -> GROUP BY registrado.producto_id
    -> ORDER BY max_suma DESC
    -> LIMIT 1;
+----------+
| max_suma |
+----------+
|       20 |
+----------+
1 row in set (0.00 sec)

Ahora, este valor LO PUEDES UTILIZAR EN LA PRIMER CONSULTA para filtrar aquellos registros que tengan esta misma SUMA, también podrías hacerlo con una consulta, pero es más simple si lo haces UTILIZANDO LA CLÁUSULA HAVING, para hacerlo de manera directa;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
mysql> SELECT
    ->   registrado.producto_id,
    ->   SUM(registrado.unidades) suma
    -> FROM registrado
    -> INNER JOIN venta ON venta.id = registrado.venta_id
    -> WHERE
    ->   venta.cliente_id = 4 AND
    ->   MONTH(venta.fecha) = 11
    -> GROUP BY registrado.producto_id
    -> HAVING
    ->   SUM(registrado.unidades) =
    ->   ( SELECT
    ->       SUM(registrado.unidades) max_suma
    ->     FROM registrado
    ->     INNER JOIN venta ON venta.id = registrado.venta_id
    ->     WHERE
    ->       venta.cliente_id = 4 AND
    ->       MONTH(venta.fecha) = 11
    ->     GROUP BY registrado.producto_id
    ->     ORDER BY max_suma DESC
    ->     LIMIT 1
    ->   );
+-------------+------+
| producto_id | suma |
+-------------+------+
|           4 |   20 |
|           5 |   20 |
+-------------+------+
2 rows in set (0.00 sec)

que es el resultado que esperas. Dale un vistazo y nos comentas (En tu post dices que son los productos 4 y 6 pero creo que es un error con los datos, deben ser 4 y 5)

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
sin imagen de perfil
Val: 10
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

CONSULTA SQL

Publicado por Guillermo (5 intervenciones) el 25/11/2017 00:49:14
Hola Leo, tienes razón, me he equivocado al escribirlo, la solución es el 4 y el 5, si ni si quiera hay id 6, muchísimas gracias por tu explicación tan detallada, se entiende perfectamente, además he podido probarlo paso por paso, e ir viendo cada tabla a la perfección, lo he completado de la siguiente manera para ver los datos de los productos, funciona, tú lo ves bien?

SELECT `id`,`nombre`,`precio`,`unidades`,`activo` FROM producto INNER JOIN
(SELECT registrado.producto_id, SUM(registrado.unidades) suma FROM registrado
INNER JOIN venta ON venta.id = registrado.venta_id WHERE venta.cliente_id = 4 AND MONTH(venta.fecha) = 11 GROUP BY registrado.producto_id
HAVING SUM(registrado.unidades) = ( SELECT SUM(registrado.unidades) max_suma
FROM registrado INNER JOIN venta ON venta.id = registrado.venta_id WHERE venta.cliente_id = 4 AND MONTH(venta.fecha) = 11
GROUP BY registrado.producto_id ORDER BY max_suma DESC LIMIT 1 ) )
AS MaxProductos ON MaxProductos.producto_id = producto.id

Muchas gracias otra vez por la ayuda!!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar