como hacer esta consulta anidada?

Matjazz

asdf
Se incorporó
18 Agosto 2007
Mensajes
1.196
Hola

Resulta que tengo un modelo que tiene las sucursales y los productos de cada sucursal.

las tablas tienen

Sucursales (ID_sucursal, nombre)
Productos (ID_producto, precio, ID_sucursal) siendo en este caso ID_sucursal una FK.

como puedo obtener los 10 productos de precio mas alto por cada sucursal?

traté con esta consulta pero no funciona
PHP:
SELECT ID_sucursal AS suc
FROM Sucursales, (select * from productos where ID_sucursal='SUC' ORDER BY precio DESC LIMIT 10);

El error que me tira es Error Code: 1241. Operand should contain 1 column(s)

Está bien usar la subconsulta en el from? Alguna idea?
 

GORDIO

Tatita del Ritmo
Se incorporó
30 Agosto 2005
Mensajes
2.096
creo que la cosa va por aqui:

Código:
select * from productos 
where id_suc = :variable_con_idsuc
order by precio DESC limit 10 ;

AL parecer no es necesario un select anidado
 
Upvote 0

Zuljin

Fundador
Miembro del Equipo
Fundador
ADMIN
Se incorporó
15 Enero 2004
Mensajes
11.777
Hola

Resulta que tengo un modelo que tiene las sucursales y los productos de cada sucursal.

las tablas tienen

Sucursales (ID_sucursal, nombre)
Productos (ID_producto, precio, ID_sucursal) siendo en este caso ID_sucursal una FK.

como puedo obtener los 10 productos de precio mas alto por cada sucursal?

traté con esta consulta pero no funciona
PHP:
SELECT ID_sucursal AS suc
FROM Sucursales, (select * from productos where ID_sucursal='SUC' ORDER BY precio DESC LIMIT 10);

El error que me tira es Error Code: 1241. Operand should contain 1 column(s)

Está bien usar la subconsulta en el from? Alguna idea?

Interesante. Llegando a la casa hago una prueba y te comento.
 
Upvote 0

Matjazz

asdf
Se incorporó
18 Agosto 2007
Mensajes
1.196
creo que la cosa va por aqui:

Código:
select * from productos 
where id_suc = :variable_con_idsuc
order by precio DESC limit 10 ;

AL parecer no es necesario un select anidado
Esa consulta me va a dar 10 producto de alguna sucursal en especifico.

Y necesito 10 productos por cada sucursal, los más caros de cada una de ellas
 
Upvote 0

GORDIO

Tatita del Ritmo
Se incorporó
30 Agosto 2005
Mensajes
2.096
Quiza esto podria funcionar :


Código:
select * from producto as a 
where [COLOR=#CDCDCD]precio in (select top 10 from producto as b where a.id_suc = b.id_suc order by precio DESC )
[/COLOR]order by id_suc ASC, precio DESC
 
Upvote 0

nibal2

pajarón nuevo
MOD
Se incorporó
15 Junio 2007
Mensajes
2.897
Tienes datos de prueba? Se ve entretenido el desafío, pero me da paja crear la db y llenarla para probar
 
Upvote 0

Matjazz

asdf
Se incorporó
18 Agosto 2007
Mensajes
1.196
Quiza esto podria funcionar :


Código:
select * from producto as a 
where [COLOR=#CDCDCD]precio in (select top 10 from producto as b where a.id_suc = b.id_suc order by precio DESC )
[/COLOR]order by id_suc ASC, precio DESC

Transporte el codigo a mysql (basicamente cambiarle el top por limit) y me tiró el mismo error
Error Code: 1241. Operand should contain 1 column(s)

Esto mismo, si me tocara hacerlo en php+mysql lo haria de esta forma:

PHP:
$sucursales = mysql_query("SELECT * FROM sucursales");
while($suc_array = mysql_fetch_array($sucursales)){
    $precios = mysql_query("SELECT * FROM precios WHERE id_sucursal='$suc_array[id_sucursal] ORDER BY precio DESC LIMIT 10");
}

Se entiende un poco mas la idea?

se requieren lo 10 productos mas caros de cada sucursal. Uno que no es muy experto en mysql lo haría con un ciclo fuera de la consulta... pero ahora requiero meter ese mismo ciclo dentro de la consulta.

Por lo mismo dedusco que la subconsulta es la que debe tener el LIMIT 10.

- - - Updated - - -

Tienes datos de prueba? Se ve entretenido el desafío, pero me da paja crear la db y llenarla para probar

shuta no tengo datos, solo el modelo.
 
Upvote 0

Batou

%安全
Se incorporó
13 Julio 2008
Mensajes
497
Transporte el codigo a mysql (basicamente cambiarle el top por limit) y me tiró el mismo error
Error Code: 1241. Operand should contain 1 column(s)

Esto mismo, si me tocara hacerlo en php+mysql lo haria de esta forma:

PHP:
$sucursales = mysql_query("SELECT * FROM sucursales");
while($suc_array = mysql_fetch_array($sucursales)){
    $precios = mysql_query("SELECT * FROM precios WHERE id_sucursal='$suc_array[id_sucursal] ORDER BY precio DESC LIMIT 10");
}

Se entiende un poco mas la idea?

se requieren lo 10 productos mas caros de cada sucursal. Uno que no es muy experto en mysql lo haría con un ciclo fuera de la consulta... pero ahora requiero meter ese mismo ciclo dentro de la consulta.

Por lo mismo dedusco que la subconsulta es la que debe tener el LIMIT 10.

- - - Updated - - -



shuta no tengo datos, solo el modelo.


mm creo que haberme topado con ese problema antes,, y seguramente para no calentarme la cabeza lo hice en php como dices.

El problema creo que es porque tienes que obtener 10 filas por cada sucursal y si usas un Group by no te va a pescar ni el order ni el limit.

Sin embargo se me ocurrio algo, crear un registro por cada sucursal y un string con group_concat en el cual estan los 10 precios mas altos con separados con una coma.


algo asi:

Código:
SELECT a.descripcion as SUCURSAL,(SELECT substring_index(group_concat(c.producto ORDER BY c.precio desc),',',10) FROM productos AS c WHERE c.id_sucursal=a.id_sucursal) AS producto FROM sucursales AS a;

Luego simplemente separas por la coma en php.

Saludos.
 
Upvote 0

Zuljin

Fundador
Miembro del Equipo
Fundador
ADMIN
Se incorporó
15 Enero 2004
Mensajes
11.777
Ja, que complicado el problema. Acabo de montar una basecilla mysql con datos demo y la verdad es que es complicado hacer todo en una sola sentencia sql. Voy a jugar un poco más por si se me ocurre algo.
 
Upvote 0

Matjazz

asdf
Se incorporó
18 Agosto 2007
Mensajes
1.196
mm creo que haberme topado con ese problema antes,, y seguramente para no calentarme la cabeza lo hice en php como dices.

El problema creo que es porque tienes que obtener 10 filas por cada sucursal y si usas un Group by no te va a pescar ni el order ni el limit.

Sin embargo se me ocurrio algo, crear un registro por cada sucursal y un string con group_concat en el cual estan los 10 precios mas altos con separados con una coma.


algo asi:

Código:
SELECT a.descripcion as SUCURSAL,(SELECT substring_index(group_concat(c.producto ORDER BY c.precio desc),',',10) FROM productos AS c WHERE c.id_sucursal=a.id_sucursal) AS producto FROM sucursales AS a;

Luego simplemente separas por la coma en php.

Saludos.

gracias, pero no entendí niuna la consulta jajaja...

y puta, lo necesito resolver en mysql ya que esto pasara a un informe que lo harán en otra capa.
 
Upvote 0

Zuljin

Fundador
Miembro del Equipo
Fundador
ADMIN
Se incorporó
15 Enero 2004
Mensajes
11.777
gracias, pero no entendí niuna la consulta jajaja...

y puta, lo necesito resolver en mysql ya que esto pasara a un informe que lo harán en otra capa.


Aguanta que la tengo casi lista. Pillé esta función que es la cumbia

SUBSTRING_INDEX

SELECT
ID_SUCURSAL,
SUBSTRING_INDEX(GROUP_CONCAT(ID_PRODUCTO ORDER BY precio DESC), ',', 3) AS top_PRECIOS_SUCURSAL
FROM
PRODUCTOS
GROUP BY
ID_SUCURSAL
 
Upvote 0

Zuljin

Fundador
Miembro del Equipo
Fundador
ADMIN
Se incorporó
15 Enero 2004
Mensajes
11.777
Ya, terminé. Hice una query en donde muestro los 3 productos con el precio más alto por sucursal. No lo hice con más porque las tablas las completé con pocos datos, pero ahí tú cambias los números. La magia está en las funciones que te destaqué.


SELECT
NOMBRE,
P.ID_SUCURSAL,
PRECIO
FROM
PRODUCTOS P,
SUCURSALES S,
(
SELECT
GROUP_CONCAT(top_precios_por_sucursal) AS top_precios
FROM
(
SELECT
SUBSTRING_INDEX(GROUP_CONCAT(ID_PRODUCTO ORDER BY precio DESC), ',', 3) AS top_precios_por_sucursal
FROM
PRODUCTOS
GROUP BY
ID_SUCURSAL
) s_top_precios_por_sucursal
) s_top_precios
WHERE
FIND_IN_SET(ID_PRODUCTO, top_precios)
AND S.ID_SUCURSAL = P.ID_SUCURSAL
ORDER BY
P.ID_SUCURSAL, PRECIO DESC
 
Upvote 0

Matjazz

asdf
Se incorporó
18 Agosto 2007
Mensajes
1.196
Ya, terminé. Hice una query en donde muestro los 3 productos con el precio más alto por sucursal. No lo hice con más porque las tablas las completé con pocos datos, pero ahí tú cambias los números. La magia está en las funciones que te destaqué.


SELECT
NOMBRE,
P.ID_SUCURSAL,
PRECIO
FROM
PRODUCTOS P,
SUCURSALES S,
(
SELECT
GROUP_CONCAT(top_precios_por_sucursal) AS top_precios
FROM
(
SELECT
SUBSTRING_INDEX(GROUP_CONCAT(ID_PRODUCTO ORDER BY precio DESC), ',', 3) AS top_precios_por_sucursal
FROM
PRODUCTOS
GROUP BY
ID_SUCURSAL
) s_top_precios_por_sucursal
) s_top_precios
WHERE
FIND_IN_SET(ID_PRODUCTO, top_precios)
AND S.ID_SUCURSAL = P.ID_SUCURSAL
ORDER BY
P.ID_SUCURSAL, PRECIO DESC

wooow! que capo wn...

esta consulta está a otro nivel realmente.

Funciona perfect! muchas gracias!
 
Upvote 0

SeWa

Pro
Se incorporó
4 Abril 2006
Mensajes
536
Hola
PHP:
SELECT ID_sucursal AS suc
FROM Sucursales, (select * from productos where ID_sucursal='SUC' ORDER BY precio DESC LIMIT 10);

El error que me tira es Error Code: 1241. Operand should contain 1 column(s)

Un poco tarde, pero tu problema es que la consulta anidada tiene un *, es decir, retorna más de una columna, y debiese sólo retornar el "ID"

Solución, sin tanta parafernalia:

SELECT S.ID_SUCURSAL, P.ID_PRODUCTO, P.PRECIO
FROM SUCURSAL S INNER JOIN PRODUCTO P ON S.ID_SUCURSAL = P.ID_SUCURSAL
WHERE P.ID_PRODUCTO IN
(SELECT TOP 2 ID_PRODUCTO FROM PRODUCTO WHERE ID_SUCURSAL = P.ID_SUCURSAL ORDER BY PRECIO DESC)

1-1167585.png


Tabla Producto:
1-1167590.png



Reemplaza el "TOP 2" POR "LIMIT 10;"

Saludos.
 
Última modificación:
Upvote 0
Subir