Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Problema ordenando por dos campos.

Estas en el tema de Problema ordenando por dos campos. en el foro de Mysql en Foros del Web. Buenas tengo un probemilla, tengo el siguiente sp: Código: PROCEDURE `S_Articulos`(in in_nombre_marca varchar(45), in in_regInicio int, in in_regxPagina int) BEGIN select idArticulos, Articulos.Nombre,Descripcion,Precio from articulos ...
  #1 (permalink)  
Antiguo 19/03/2012, 12:56
 
Fecha de Ingreso: abril-2010
Mensajes: 298
Antigüedad: 9 años, 9 meses
Puntos: 1
Problema ordenando por dos campos.

Buenas tengo un probemilla, tengo el siguiente sp:


Código:
PROCEDURE `S_Articulos`(in in_nombre_marca varchar(45),
in in_regInicio int, in in_regxPagina int)
BEGIN
    
    select idArticulos, Articulos.Nombre,Descripcion,Precio from articulos
    inner join familias on articulos.Familias_idFamilias= familias.idFamilias
    inner join familias_has_marcas on familias.idFamilias=familias_has_marcas.Familias_idFamilias
    where 
    familias_has_marcas.Marcas_idMarcas=(select idMarcas from marcas where Nombre=in_nombre_marca)    
    order by articulos.Orden asc, familias_has_marcas.Orden asc
     limit in_regInicio, in_regxPagina;

END
Estas son las tablas:



Y estos los contenidos:
articulos:


Uploaded with ImageShack.us

familias:


Uploaded with ImageShack.us

familias_has_marcas:


Uploaded with ImageShack.us

Uploaded with ImageShack.us
Y este el resultado de la query:
2 Camisa1 desc1 1
4 Zapatilas1 desc3 1
3 Pantaloneta1 desc2 1
6 Pantaloneta2 desc5 1
5 Camisa2 desc4 1
7 Zapatilas2 desc6 1
8 Camisa3 desc7 1
9 Pantaloneta3 desc8 1
10 Zapatillas3 desc9 1

Mi intención es que muestra un listado de articulos ,segun marca de manera ordenada los resultados primero por familia.Orden y luego por artiulo.Orden, de manera que primero mostraria los 3 registros pertenecientes a la primera familia, en este caso Camisas, que serian camisa1,camisa2,camisa3 siguiendo su orden de la tabla artiulos, despues lo mismo con Pantalonetas y lo mismo con zapatillas:
Camisa1
Camisa2
Camisa3
Pantaloneta1
Pantaloneta2
Pantaloneta3
Zapatillas1
Zapatillas2
Zapatillas3

Que falla en mi query??

Gracias.

Última edición por ferminako; 19/03/2012 a las 13:09
  #2 (permalink)  
Antiguo 19/03/2012, 15:38
 
Fecha de Ingreso: agosto-2011
Mensajes: 59
Antigüedad: 8 años, 6 meses
Puntos: 8
Respuesta: Problema ordenando por dos campos.

Hola.

"Mi intención es que muestra un listado de articulos ,segun marca de manera ordenada los resultados primero por familia.Orden y luego por artiulo.Orden,"

Si eso es lo que quieres el order by lo tienes que poner también en ese orden

Ahora tienes
order by articulos.Orden asc, familias_has_marcas.Orden asc

Y lo que has puesto en el texto es

order by familias_has_marcas.Orden asc, articulos.Orden asc
  #3 (permalink)  
Antiguo 19/03/2012, 17:42
 
Fecha de Ingreso: abril-2010
Mensajes: 298
Antigüedad: 9 años, 9 meses
Puntos: 1
Respuesta: Problema ordenando por dos campos.

Ya lo he modificado y el resultado es :
2 Camisa1 desc1 1
6 Pantaloneta2 desc5 1
5 Camisa2 desc4 1
8 Camisa3 desc7 1
4 Zapatilas1 desc3 1
9 Pantaloneta3 desc8 1
3 Pantaloneta1 desc2 1
7 Zapatilas2 desc6 1
10 Zapatillas3 desc9 1

Sigue sin ser lo que busco :S

Gracias de tdas maneras , a ver si alguien da con el problema ;)
  #4 (permalink)  
Antiguo 19/03/2012, 19:12
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.322
Antigüedad: 12 años, 2 meses
Puntos: 2654
Respuesta: Problema ordenando por dos campos.

En el contexto de los datos que muestras de ejemplo, esto alcanzaría para dar el resultado esperado:
Código MySQL:
Ver original
  1.     A.idArticulos,
  2.     A.Nombre,
  3.     A.Descripcion,
  4.     A.Precio
  5.     articulos A
  6.     INNER JOIN familias F ON A.Familias_idFamilias = F.idFamilias
  7.     INNER JOIN familias_has_marcas FTM ON F.idFamilias = FTM.Familias_idFamilias
  8.     INNER JOIN marcas M ON FTM.Marcas_idMarcas = M.idMarcas
  9. ORDER BY A.Nombre, A.Descripcion
En cuanto a lo que está mal, hay varios puntos a considerar:
1) El stored procedure no funcionará, porque LIMIT no admite uso de variables de ningún tipo. Sólo números naturales.
2) Las tablas contienen redundancia de datos. Poner, por ejemplo, un campo "orden", que es un espejo de lo que aparece en otros (familias_id, marcas_familia_id, etc), hace que el campo se vuelva irrelevante.
3) Las PK estan mal construidas, porque permiten inconsistencias al crearlas compuestas de un id incremental, mas otros campos. Así, se podría insertar varias veces el mismo producto con sólo variar el id incremental que es parte de la clave.
4) La tabla de relación N:M, está mal construida, porque su clave debería ser de dos campos y no de tres. Sólo se admitiría un discriminante (no autoincremental), si la misma familia puede corresponder a la misma marca mas de una vez... algo poco probable.
5) La relación entre familia y artículo es redundante, porque ya está establecida por la relación entre familia y marca, o bien la de marca está de más porque familia y marca ya lo están. Una de las dos relaciones con artículo debe ser eliminada.
6) Los ORDER BY por defecto son siempre ASC. Si vas a hacer listados ordenados en forma ascendente, es innecesario ponerlo.
7) El orden de información que estás buscando es en definitiva un orden alfabético, por lo que el campo "orden" resulta innecesario, ya que ese tipo de orden se puede lograr con sólo los de descripción y nombre.

Finalmente: Necesitarías volver a revisar los conceptos de integridad, consistencia y unicidad en el modelo relacional. Allí es donde estás fallando.
Vuelve atrás y analiza tu diagrama en base a los fundamentos del modelo E-R. Podrás ver por dónde no se están cumpliendo.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 20/03/2012, 04:59
 
Fecha de Ingreso: abril-2010
Mensajes: 298
Antigüedad: 9 años, 9 meses
Puntos: 1
Respuesta: Problema ordenando por dos campos.

De acuerdo, voy a darle una vuelta a la base de datos, pero la ordenacion no es alfabetica sino segun los campos orden de familias_has_marcas y despues del orden del articulo, dado que el usuario final , desde el backend variara esos campos orden, para mostrarlos items como guste.
Por lo tanto como seria la sql para obtener los datos con la ordenación que te comento???

1)EL sp funciona pues solo se le pasan valores enteros como 1,10.
2)creo que el campo no es irrelevante puesto que el usuario final modificara estos registros para visualizar los como guste.
5)la relacion entre articulo y familia no me parece redundante puesto que sin ella no es posible saber de que familia es un articulo no???
Porque solo tendria la marca y la marca pertenece a distintas familias, por lo tanto me seria imposible saber a que familia corresponde un articulo.
Muchas gracias por tu analisis gnzsoloyo, es de gran ayuda.

Última edición por ferminako; 20/03/2012 a las 05:24
  #6 (permalink)  
Antiguo 20/03/2012, 05:29
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.322
Antigüedad: 12 años, 2 meses
Puntos: 2654
Respuesta: Problema ordenando por dos campos.

Cita:
1)EL sp funciona pues solo se le pasan valores enteros como 1,10.
El LIMIT no admite variables.
2) Los ordenamientos personalizados no necesitan de campos adicionales, sino de ORDEN BY.
5) Falso: Eso se recrea sobre la base de los JOIN que se usan en la consulta. La relación es redundante y puede plantear problemas a futuro.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 20/03/2012, 05:59
 
Fecha de Ingreso: abril-2010
Mensajes: 298
Antigüedad: 9 años, 9 meses
Puntos: 1
Respuesta: Problema ordenando por dos campos.

No entiendo lo de las variables del limit , yo le estoy pasando los registros que necesito ver por parametro y me lo esta congiendo... call S_Articulos(1,0,9)... de todas maneras esto no es relevante ahora.

Entonces como harias el ordenamiento tu? porque a mi solo se me ocurrio eso , puesto que el usuario elije como salen los articulos, el dice de la marca Addidas, salen primero la familia camisas luego los calzoncillos luego... y dentro de cada familia para esa marca (familias_has_marcas) tb llevan un orden. por lo tanto no se como solucionarlo sin ese campo orden en ambas tablas... como lo harias tu?

Y en ese caso que query necesitaria, todo esto teniendo en cuenta que elimino la relacion entre arituculos y familias ;)

Gracias!
  #8 (permalink)  
Antiguo 20/03/2012, 09:33
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.322
Antigüedad: 12 años, 2 meses
Puntos: 2654
Respuesta: Problema ordenando por dos campos.

Bueno, el caso del LIMIT te está funcionando sólo porque usas una versión 5.5.6 o superior, ya que antes de eso LIMIT no admitía el uso de variables locales para ingresar los parámetros.
Cita:
Manual de referencia:
Within stored programs, LIMIT parameters can be specified using integer-valued routine parameters or local variables as of MySQL 5.5.6.
El tema de los ordenamientos personalizados y personalizables es bastante extenso, y se pueden resolver tanto dentro de las consultas, como en la base de datos. Hacerlo en uno u otro, depende de la decisión de diseño, principalmente, pero hay algunas cosas a considerar.
- En la aplicación es conveniente cuando la haces sobre la misma cantidad de registros devueltos incialmente, y normalmente se hace operando sobre la vista que presenta en pantalla, o los headers de las tablas.
- En la base, es coveniente cuando es un nuevo bloque de datos, pero no tiene ningún sentido hacer que repetidamente se realicen consultas sólo para obtener los mismos datos ordenados de diferentes formas.
- Un listado de orden fijo sólo sirve si se trata de reportes de estructura fija, pero no sirven para el uso general.
- Jamás puedes anticipar cómo va a querer el orden un usuario cualquiera. No puedes, porque con sólo que haya dos usuarios en dos momentos distintos, puedes tener dos o más formas de ordenar las cosas, según sea la necesidad de cada uno. Diferentes necesidades de resumenes de la misma información pueden producir ordenamientos distintos.
- Cuando ordenas en base a una o más columnas, y la seleccion del orden la hace al inicio el usuario, lo que haces es crear dinámicamente la consulta para que salga ordenada según quiere.
- Si el ordenamiento que se desea incluye ordenar juntos items que tienen una característica común (en la ropa, podrían ser Zapato, Pantalón, Pollera, etc), estas características no deben formar parte de la denominación, sino ser un atributo de la entidad representada, de modo de poder ser usado directamente como parámetro del ORDER BY.
- Puede también darse la situación de que este atributo pueda tener suficiente entidad como para ser independiente, y en ese caso estamos ante una relación entre dos entidades, donde ese atributo pasa a ser una foreign key. Esto facilita el proceso de crear el ORDER BY correcto. Tal es el caso de los conceptos de "categoría", "rubro", "clase", que puede ser tanto de objetos, como atributos de personas. En este orden, es posible que en tu modelo falten entidades (tabla), y le esté haciendo falta normalización.
- Es muy importante que comprendas, que normalmente lo que se hace en estos casos de ordenamiento personalizable, es crear la sentencia de consulta dinámicamente, y no en un SP que sólo te puede dar un orden fijo. Hay muchos ejemplos de cómo hacer eso en los foros de los diferentes lenguajes. Busca allí (este es MySQL, no se pone programación acá).

Finalmente, para que entiendas por qué es redundante la relación: Es por la transitividad de la relación:
Cita:
Si A está relacionado con B, y B está relacionado con C, entonces A está relacionado con C por medio de B.
¿Se entiende el concepto?
Entonces, si la relación es:
Cita:
Articulo -> Marca
Familia -> Familia_tiene_Marca
Marca -> Familia_tiene_Marca
entonces:
Cita:
Articulo -> Familia -> Familia_tiene_Marca -> Marca.
Lo que en SQL es:
Código MySQL:
Ver original
  1.     A.idArticulos,
  2.     A.Nombre,
  3.     A.Descripcion,
  4.     A.Precio
  5.     articulos A
  6.     INNER JOIN familias F ON A.Familias_idFamilias = F.idFamilias
  7.     INNER JOIN familias_has_marcas FTM ON F.idFamilias = FTM.Familias_idFamilias
  8.     INNER JOIN marcas M ON FTM.Marcas_idMarcas = M.idMarcas
  9. ORDER BY A.Nombre, A.Descripcion
Obviamente, esto implica que sólo podrá devolver aquellos registros que cumplan todas las condiciones.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 20/03/2012, 11:10
 
Fecha de Ingreso: abril-2010
Mensajes: 298
Antigüedad: 9 años, 9 meses
Puntos: 1
Respuesta: Problema ordenando por dos campos.

Entendido, se agradece la explicación :)
En este caso el sistema lo lleva un solo usuario y solo quiere que se se ordene por ese campo, es por eso que necesito la query segun familias_has_marcas.Orden, y segun articulos.orden.

Por lo tanto la consulta correcta deberia seR esta?¿
Código SQL:
Ver original
  1. `S_Articulos`(IN in_nombre_marca VARCHAR(45),
  2. IN in_regInicio INT, IN in_regxPagina INT)
  3. BEGIN
  4.    
  5.     SELECT idArticulos, Articulos.Nombre,Descripcion,Precio FROM articulos
  6.     INNER JOIN familias ON articulos.Familias_idFamilias= familias.idFamilias
  7.     INNER JOIN familias_has_marcas ON familias.idFamilias=familias_has_marcas.Familias_idFamilias
  8.     WHERE
  9.     familias_has_marcas.Marcas_idMarcas=(SELECT idMarcas FROM marcas WHERE Nombre=in_nombre_marca)    
  10.     ORDER BY familias_has_marcas.Orden, articulos.Orden
  11.      LIMIT in_regInicio, in_regxPagina;
  12. END

Pero sigue sin funcionarme, he metido un articulo de otra marca(id2) todos los demas son de la marca id=1 y tb me lo mete en el resultado... call S_Articulos(1,0,10) me los saca todos correctos con el orden que buscaba pero me incluye el articulo cuyo idMarca es =2 , algun join deberia ser lef t o right? tiene q ser algo asi no?

gracias gnzsoloyo por todas tus explicaciones y tomarte el tiempo en revisar mi trabajo ;)

Por cierto como apsarias pues los dos parametros del limit si no puedo utilizar variables???

Última edición por ferminako; 20/03/2012 a las 11:46
  #10 (permalink)  
Antiguo 20/03/2012, 17:34
 
Fecha de Ingreso: abril-2010
Mensajes: 298
Antigüedad: 9 años, 9 meses
Puntos: 1
Respuesta: Problema ordenando por dos campos.

con lo de la version 5.5.6 te refieres a mysql?

Etiquetas: join, query, registros, select, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 13:03.