MySQL - ¿Optimizar dos consultas en una sola?

 
Vista:
Imágen de perfil de David
Val: 16
Ha disminuido 1 puesto en MySQL (en relación al último mes)
Gráfica de MySQL

¿Optimizar dos consultas en una sola?

Publicado por David (12 intervenciones) el 14/09/2018 11:11:10
Hola a todos!

Os explico un poco...

Tengo una tabla "usuarios" y se debe mirar si existe algún valor en el campo "precio_normal" y en el campo "precio_socios". Posteriormente según exista valor en uno u otro campo se debe buscar info en tablas diferentes: tabla "precios_normales" o tabla "precios_socios".

El tema está en que yo ahora lo hago con dos select:
1º- Miro si existe valor en alguno de los dos campos de la tabla usuarios
2º - Si existe valor en campo "precio_normal" realizo otro select para extraer info de la tabla "precios_normales" y si existe valor en campo "precio_socios" realizo otro select para extraer info de la tabla "precios_socios"

¿Existe alguna forma de poder hacerlo en un solo select (supongo que sería más optimizado y podría ordenar, etc.)?

Gracias.
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: 953
Oro
Ha mantenido su posición en MySQL (en relación al último mes)
Gráfica de MySQL

¿Optimizar dos consultas en una sola?

Publicado por Leonardo Josué (414 intervenciones) el 14/09/2018 23:27:54
Hola David:

Veamos si esto te puede servir:

Supongamos que tienes esta tabla:

1
2
3
4
5
6
7
8
9
10
mysql> select * from tabla_a;
+------+-------------+---------------+--------------+
| id   | descripcion | precio_normal | precio_socio |
+------+-------------+---------------+--------------+
|    1 | uno         |            11 |         NULL |
|    2 | dos         |          NULL |           22 |
|    3 | tres        |          NULL |         NULL |
|    4 | cuatro      |            44 |           44 |
+------+-------------+---------------+--------------+
4 rows in set (0.00 sec)

Aquí se observan dos columnas de precios, y todas las combinaciones posibles (es decir, sólo una columna tiene valor, ambas columnas tienen valor o ninguna columna tiene valor)

supongamos entonces que tienes dos tablas "catálogos", así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> select * from precios_normales;
+---------------+-----------------+--------+
| precio_normal | descripcion     | precio |
+---------------+-----------------+--------+
|            11 | precio normal 1 |     10 |
|            44 | precio normal 4 |     25 |
+---------------+-----------------+--------+
2 rows in set (0.00 sec)
 
mysql> select * from precios_socios;
+--------------+----------------+--------+
| precio_socio | descripcion    | precio |
+--------------+----------------+--------+
|           22 | precio socio 2 |     10 |
|           44 | precio socio 4 |     40 |
+--------------+----------------+--------+
2 rows in set (0.00 sec)

entonces, para obtener la información de cada tabla asociada, puedes hacer un doble LEFT JOIN a los catálogos:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql> select
    ->   tabla_a.id, tabla_a.descripcion,
    ->   precios_normales.precio_normal, precios_normales.descripcion, precios_normales.precio,
    ->   precios_socios.precio_socio, precios_socios.descripcion, precios_socios.precio
    -> from tabla_a
    -> left join precios_normales on precios_normales.precio_normal = tabla_a.precio_normal
    -> left join precios_socios   on precios_socios.precio_socio = tabla_a.precio_socio
    -> order by tabla_a.id;
+------+-------------+---------------+-----------------+--------+--------------+----------------+--------+
| id   | descripcion | precio_normal | descripcion     | precio | precio_socio | descripcion    | precio |
+------+-------------+---------------+-----------------+--------+--------------+----------------+--------+
|    1 | uno         |            11 | precio normal 1 |     10 |         NULL | NULL           |   NULL |
|    2 | dos         |          NULL | NULL            |   NULL |           22 | precio socio 2 |     10 |
|    3 | tres        |          NULL | NULL            |   NULL |         NULL | NULL           |   NULL |
|    4 | cuatro      |            44 | precio normal 4 |     25 |           44 | precio socio 4 |     40 |
+------+-------------+---------------+-----------------+--------+--------------+----------------+--------+
4 rows in set (0.00 sec)

Si hay información relacionada, entonces se mostrará el valor, de lo contrario quedarán como NULL... ahora bien, si sólo quieres mostrar uno de los precios, entonces tendrías que hacer una condición tipo CASE-WHEN más o menos así:

1
2
3
4
5
6
SELECT
...
CASE WHEN precio_normal.precio IS NOT NULL THEN precio_normal.precio ELSE precios_socios.precio END
...
FROM
...

Si tienes el caso que puedan venir los dos precios (como en el último ejemplo) entonces podrías validar para que te dé el más alto o el más bajo, según lo requieras.

Haz la prueba y nos comentas.

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
2
Comentar
Imágen de perfil de David
Val: 16
Ha disminuido 1 puesto en MySQL (en relación al último mes)
Gráfica de MySQL

¿Optimizar dos consultas en una sola?

Publicado por David (12 intervenciones) el 15/09/2018 09:40:30
Muy interesante! Eres un crack!

Muchas gracias lo probaré!
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
Imágen de perfil de David
Val: 16
Ha disminuido 1 puesto en MySQL (en relación al último mes)
Gráfica de MySQL

¿Optimizar dos consultas en una sola?

Publicado por David (12 intervenciones) el 19/09/2018 18:34:01
Funciona muy requetebien!

Un par de dudas para liar más el tema xddd:
- El CASE-WHEN no me funciona, me da error mysql, seguramente sea culpa mía. ¿Como sería exactamente la sentencia?
- ¿Se podría ordenar por "precio_normal" y "precio_socio" como si fuera un solo campo "precio" (order by "precio")

Mil gracias.
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: 953
Oro
Ha mantenido su posición en MySQL (en relación al último mes)
Gráfica de MySQL

¿Optimizar dos consultas en una sola?

Publicado por Leonardo Josué (414 intervenciones) el 19/09/2018 23:12:43
Hola de nuevo David:

Vayamos por partes:

1
2
- El CASE-WHEN no me funciona, me da error mysql, seguramente sea culpa mía. ¿Como sería exactamente
la sentencia?

Cuando MySQL Te arroje un error, debes de decirnos cuál es ese error, o al menos poner el código que estás intentando hacer, ya que en el foro lamentablemente no hay muchos adivinos ¬¬

La Sintaxis de la condicion CASE - WHEN tiene dos variantes, una que funciona como una sentencia SWITCH de lenguajes de programación o como sentencia IF. En este caso, la sentencia sería más o menos del estilo de la que puse en el ejemplo:

1
2
3
4
CASE WHEN precio_normal.precio IS NOT NULL
  THEN precio_normal.precio
  ELSE precios_socios.precio
END

es decir la sintaxis es así:

1
2
3
4
CASE WHEN condicion
  THEN valor_si_la_condicion_es_verdadera
  ELSE valor_si_la_condicion_es_falsa
END

1
2
- ¿Se podría ordenar por "precio_normal" y "precio_socio" como si fuera un solo
campo "precio" (order by "precio")

No, cuando se ordena por más de un campo, lo que haces es ordenar Secuencialmente, es decir, ordena todos los registros por el primer criterio y después "vuelve a ordenar" los registros pero considerando el segundo criterio. En todo caso, puedes hacer una ordenación ESPECIAL con un CASE WHEN o utilizando algún otro operador como CONCAT o IF para tomar ambos campos como si fuera uno, pero deberías decirnos un ejemplo de tus datos y cómo quieres ordenarlos, así podríamos indicarte alguna opción para el ORDER BY.

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