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

[SOLUCIONADO] JOIN con preferencia

Estas en el tema de JOIN con preferencia en el foro de Mysql en Foros del Web. Buenos días. Necesito ayuda con una consulta que me tiene loco, no se si esta de forma correcta así o si hay formas mejores. Tengo ...
  #1 (permalink)  
Antiguo 15/12/2015, 06:36
 
Fecha de Ingreso: diciembre-2015
Mensajes: 8
Antigüedad: 8 años, 4 meses
Puntos: 0
Pregunta JOIN con preferencia

Buenos días. Necesito ayuda con una consulta que me tiene loco, no se si esta de forma correcta así o si hay formas mejores.

Tengo dos tablas una tabla llamada articulos y otra tabla llamada tiendas_articulos cuya estructura, simplificando, seria algo asi

ARTICULOS
  • ID
  • Nombre

TIENDAS_ARTICULOS
  • TiendaID
  • ArticuloID
  • Precio

Bien pues yo quiero hacer un select de X articulos. En el cual {tienda} es la tienda preferida, si el articulo existe en esa tienda, me mostrara el precio en el que se encuentra en esta tienda en concreto. Si no existe en {tienda} quiero que me devuelva el precio de cualquier otra tienda. Tengo hecho esto

Código SQL:
Ver original
  1. SELECT articulos.Nombre,TiendaID,Precio
  2. FROM articulos JOIN tiendas_articulos ON ( articulos.ID = tiendas_articulos.ArticuloID AND ( TiendaID = {tienda}OR TiendaID != {tienda} ) )
  3. WHERE articulos.ID = {articulo}

Ahora bien, en las pruebas que he hecho funciona medianamente bien, pero no se si es solo casualidad o he de hacer la consulta de otra manera. ¿Hay alguna otra forma que funcione o es esta forma la correcta? Un saludo y muchas gracias

Última edición por gnzsoloyo; 15/12/2015 a las 06:49
  #2 (permalink)  
Antiguo 15/12/2015, 06:52
Avatar de 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: JOIN con preferencia

Lo que has hecho no tengo un adjetivo adecuado para decirlo. A nivel de SQL, eso es una consulta basura, disculpa que te lo diga. Eso NO se hace.
Lo que quieres hacer no se realiza con una consulta. Se hace por STORED PROCEDURE.

En un stored procedure puedes jerarquizar la búsqueda, haciendo que PRIMERO busque una tienda deseada, y busque otra sí y sólo si la primera consulta no devuelve datos. Ese tipo de lógica es imposible en MySQL con consultas simples. El resultado aparentemente correcto es producto de la inconsistencia de la condición, y no de un aparente resultado.

Programar consultas con OR en un JOIN no sólo es una pésima práctica, sino que te llevará a errores conceptuales gravísimos con el tiempo.
El SQL es un lenguaje de consultas muy específico, es concreto y no admite cosas como esa, porque en tal caso los resultados se vuelve inconsistentes.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 15/12/2015, 11:52
 
Fecha de Ingreso: diciembre-2015
Mensajes: 8
Antigüedad: 8 años, 4 meses
Puntos: 0
Respuesta: JOIN con preferencia

Gracias por contestar. Ya se que es una chapuza esa consulta. Estoy intentando lo del stored procedure. Ahora bien te momento tengo lo siguiente.

Código MySQL:
Ver original
  1.     DECLARE precio INT;
  2.     SELECT *, precio from lists_prods
  3.     JOIN productos ON lists_prods.prodID = productos.ID
  4.     WHERE listID = value_lista;
  5.    
  6.     SELECT supermercados_productos.precio from supermercados_productos      WHERE   supermercados_productos.cod = productos.ID and                  supermercados_productos.supermercadoID = value_super  INTO precio;
  7.    
  8.     IF precio = NULL THEN  
  9.         SELECT supermercados_productos.precio from supermercados_productos         WHERE    supermercados_productos.cod = productos.ID and                     supermercados_productos.supermercadoID = value_super  INTO precio;
  10.      END IF;
  11.  

Mi problema es ahora que el precio me da null, me he quedado completamente bloqueado llevo casi una hora haciendo pruebas y no hay manera un saludo. Muchas gracias de nuevo

EDIT: Hago una aclaracion el lists_prods es una tabla con listas de productos.

Última edición por gnzsoloyo; 15/12/2015 a las 12:14
  #4 (permalink)  
Antiguo 15/12/2015, 13:23
Avatar de 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: JOIN con preferencia

Por lo pronto, un par de cosas:

1) MySQL no tiene tipos de dato TABLE, LIST, o RECORDSET, y los SET y ENUM sólo aplican a tablas, y no a SP. Con esto quiero decir que no puedes pasar una lista de valores, ni recibir en un parámetro de salida (OUT) y set de datos. SOlo datos únicos.
2) Un SP puede devolver una tabla resultado, pero no como parámetro, sino como salida de la ejecución. Para recuperarla dependerá del lenguaje de programación usado (OFF TOPIC en este foro).
3) El que uses una tabla en un JOIN en una consulta de una parte del SP, no implica que las siguientes consultas puedan adivinar que vas a volver a usar la tabla. Cada vez que haces un SELECT con dos o más tablas, en el FROM de CADA UNO, se debe n indicar las tablas implicadas, y tu estás omitiendo una tabla en las dos consultas finales.

A nivel de programación de SP, lo más simple, si vas a hacer una cosa u otra dependiendo de la existencia de un dato, es simplemente validar primero ese dato e una condición TRUEJ/FALSE, y no recopilar el dato respuesta al principio. Consumirás menos recursos y la lógica será más simple.

Para tu caso lo que necesitas es sólo el ID del supermercado que buscas, le resto sería lógica:
Código MySQL:
Ver original
  1. CREATE PROCEDURE ListaPrecios(IN idSuper INT, IN idProducto INT)
  2.     DECLARE existe DEFAULT '0';
  3.  
  4.     SELECT COUNT(1)
  5.     FROM ists_prods LP
  6.     WHERE P.ID = idProducto
  7.     INTO existe;
  8.    
  9.     IF existe ¡= 0 THEN
  10.         -- Existe el producto al menos en un super.
  11.         SET existe = 0;
  12.         SELECT COUNT(1)
  13.         FROM supermercados_productos SP
  14.         WHERE superID = idSuper AND productoID = IdProducto
  15.         INTO existe;
  16.         IF existe ¡= 0 THEN
  17.             SELECT SP.*
  18.             FROM supermercados_productos
  19.             WHERE cod = idProducto AND supermercadoID = SUperID;
  20.         ELSE
  21.             SELECT SP.*
  22.             FROM supermercados_productos
  23.             WHERE cod = idProducto AND supermercadoID ¡= SUperID
  24.             ORDER BY RND()
  25.             LIMIT 1;
  26.          END IF;
  27.     ELSE
  28.         SELECT -1 error, 'NO existe l producto' Msj;
  29.     END IF;
__________________
¿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 17/12/2015, 04:50
 
Fecha de Ingreso: diciembre-2015
Mensajes: 8
Antigüedad: 8 años, 4 meses
Puntos: 0
Respuesta: JOIN con preferencia

Muchísimas gracias por responder. He mirado el código y funciona perfectamente, he hecho unas modificaciones y me da lo siguiente como resultado, funciona bien pero no me lo da todo junto he intentado hacer UNION ALL y otras cosas y no he conseguido juntarlo todo en un mismo resultado, esto es a lo que me refiero.

El código es el siguiente


Las variables de entrada son value_lista y value_super



Un saludo y muchísimas gracias por todo, he aprendido un montón Si no fuera posible juntarlo todo con esto me daria mas que por satisfecho, he aprendido mucho, voy a pasar todas mis consultas complejas a SP.


EDITADO: Estoy probando y no me vale este SP ya que solo obtengo el primer resultado. Necesito juntar todos los resultados. ¿Alguna idea? Un saludo

EDITADO2: He probado a crear una tabla temporal pero no se si es una buena solución.

EDITADO3: Funciona bien el unico problema es que el select * from outtable solo me funciona dentro del bucle por lo que vuelvo a obtener 3 resultados, de los cuales el ultimo tiene todos los elementos, asi que no me sirve. ¿Alguna idea nueva?

EDITADO4: SOLUCIONADO muchas gracias a todos

Última edición por copralia; 17/12/2015 a las 06:56

Etiquetas: join, 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 00:01.