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

restas y sumas en resultados de busquedas

Estas en el tema de restas y sumas en resultados de busquedas en el foro de Mysql en Foros del Web. buenos dias a todos, mi pregunta es simple, ¿existe en mysql alguna manera de realizar lo que los comandos INTERSECT y EXCEPT hacen en sql ...
  #1 (permalink)  
Antiguo 28/09/2011, 14:29
 
Fecha de Ingreso: junio-2011
Ubicación: Mexicali, BC
Mensajes: 17
Antigüedad: 12 años, 9 meses
Puntos: 0
restas y sumas en resultados de busquedas

buenos dias a todos, mi pregunta es simple, ¿existe en mysql alguna manera de realizar lo que los comandos INTERSECT y EXCEPT hacen en sql server?

¿alguna manera de realizar 2 busquedas y sumar o restar sus resultados?


gracias de antemano! saludos!
  #2 (permalink)  
Antiguo 28/09/2011, 14:54
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: restas y sumas en resultados de busquedas

Hola iPaNiiCx:

En MySQL puedes utilizar los operadores INNER JOIN, LEFT JOIN y las condiciones EXISTS y NOT EXISTS para simular las operaciones INTERSECT y EXCEPT de SQL Server, checa estos scripts:

En SQL Server, sería más o menos así:

Código SQL:
Ver original
  1. DECLARE @Tabla1 TABLE(id INT, descripcion VARCHAR(10))
  2. INSERT INTO @Tabla1 VALUES (1, 'uno')
  3. INSERT INTO @Tabla1 VALUES (2, 'dos')
  4. INSERT INTO @Tabla1 VALUES (3, 'tres')
  5. INSERT INTO @Tabla1 VALUES (4, 'cuatro')
  6.  
  7. DECLARE @Tabla2 TABLE (id INT, descripcion VARCHAR(10))
  8. INSERT INTO @Tabla2 VALUES (3, 'tres')
  9. INSERT INTO @Tabla2 VALUES (4, 'cuatro')
  10. INSERT INTO @Tabla2 VALUES (5, 'cinco')
  11. INSERT INTO @Tabla2 VALUES (6, 'seis')
  12.  
  13. SELECT * FROM @Tabla1
  14. /*
  15. id          descripcion
  16. ----------- -----------
  17. 1           uno
  18. 2           dos
  19. 3           tres
  20. 4           cuatro
  21. */
  22. SELECT * FROM @Tabla2
  23. /*
  24. id          descripcion
  25. ----------- -----------
  26. 3           tres
  27. 4           cuatro
  28. 5           cinco
  29. 6           seis
  30. */
  31.  
  32.  
  33. /*Operador EXCEPT*/
  34. SELECT * FROM @Tabla1
  35. EXCEPT
  36. SELECT * FROM @Tabla2
  37. /*
  38. id          descripcion
  39. ----------- -----------
  40. 1           uno
  41. 2           dos
  42. */
  43.  
  44. /*Operador INTERSECT*/
  45. SELECT * FROM @Tabla1
  46. INTERSECT
  47. SELECT * FROM @Tabla2
  48. /*
  49. id          descripcion
  50. ----------- -----------
  51. 3           tres
  52. 4           cuatro
  53. */

Esto mismo puedes hacerlo en MySQL así:

Código MySQL:
Ver original
  1. mysql> CREATE TABLE Tabla1 (id INT, descripcion VARCHAR(10));
  2. Query OK, 0 rows affected (0.14 sec)
  3.  
  4. mysql> INSERT INTO Tabla1 VALUES (1, 'uno'), (2, 'dos'),
  5.     -> (3, 'tres'), (4, 'cuatro');
  6. Query OK, 4 rows affected (0.05 sec)
  7. Records: 4  Duplicates: 0  Warnings: 0
  8.  
  9. mysql> CREATE TABLE Tabla2 (id INT, descripcion VARCHAR(10));
  10. Query OK, 0 rows affected (0.11 sec)
  11.  
  12. mysql> INSERT INTO Tabla2 VALUES (3, 'tres'), (4, 'cuatro'),
  13.     -> (5, 'cinco'), (6, 'seis');
  14. Query OK, 4 rows affected (0.03 sec)
  15. Records: 4  Duplicates: 0  Warnings: 0
  16.  
  17. mysql> SELECT * FROM Tabla1;
  18. +------+-------------+
  19. | id   | descripcion |
  20. +------+-------------+
  21. |    1 | uno         |
  22. |    2 | dos         |
  23. |    3 | tres        |
  24. |    4 | cuatro      |
  25. +------+-------------+
  26. 4 rows in set (0.01 sec)
  27.  
  28. mysql> SELECT * FROM Tabla2;
  29. +------+-------------+
  30. | id   | descripcion |
  31. +------+-------------+
  32. |    3 | tres        |
  33. |    4 | cuatro      |
  34. |    5 | cinco       |
  35. |    6 | seis        |
  36. +------+-------------+
  37. 4 rows in set (0.00 sec)
  38.  
  39. mysql> #Pasa simular el except
  40. mysql> SELECT T1.* FROM Tabla1 T1 WHERE
  41.     -> NOT EXISTS (SELECT * FROM Tabla2 T2
  42.     -> WHERE T1.id = T2.id AND T1.descripcion = T2.descripcion);
  43. +------+-------------+
  44. | id   | descripcion |
  45. +------+-------------+
  46. |    1 | uno         |
  47. |    2 | dos         |
  48. +------+-------------+
  49. 2 rows in set (0.03 sec)
  50.  
  51. mysql> #Para simular el intersect
  52. mysql> SELECT T1.* FROM Tabla1 T1
  53.     -> INNER JOIN
  54.     -> Tabla2 T2
  55.     -> ON T1.id = T2.id AND T1.descripcion = T2.descripcion;
  56. +------+-------------+
  57. | id   | descripcion |
  58. +------+-------------+
  59. |    3 | tres        |
  60. |    4 | cuatro      |
  61. +------+-------------+
  62. 2 rows in set (0.00 sec)

Sólo tienes que cuidar definir correctamente todas tus condiciones.

Saludos
Leo
  #3 (permalink)  
Antiguo 28/09/2011, 15:29
 
Fecha de Ingreso: junio-2011
Ubicación: Mexicali, BC
Mensajes: 17
Antigüedad: 12 años, 9 meses
Puntos: 0
Respuesta: restas y sumas en resultados de busquedas

muchas gracias leonardo, me ah servido de mucho tu ayuda ya que son cosas que no conocia y me ayudaron a realizar mi query el cual era utilizando el comando UNION, gracias por tu tiempo.

Código MySQL:
Ver original
  1. mysql> select profesor.nombre, curso.nombre from profesor join curso where profe
  2. sor.noEmp = curso.noEmp and curso.nombre = "Matematicas"
  3.     -> UNION
  4.     -> select profesor.nombre, curso.nombre from profesor join curso where profe
  5. sor.noEmp = curso.noEmp and curso.nombre = "Ingles";
  6. +--------------------+-------------+
  7. | nombre             | nombre      |
  8. +--------------------+-------------+
  9. | Liliana Valenzuela | Matematicas |
  10. | Erika Lopez        | Ingles      |
  11. +--------------------+-------------+
  12. 2 rows in set (0.07 sec)
  #4 (permalink)  
Antiguo 29/09/2011, 10:00
Colaborador
 
Fecha de Ingreso: enero-2007
Ubicación: México
Mensajes: 2.097
Antigüedad: 17 años, 3 meses
Puntos: 447
Respuesta: restas y sumas en resultados de busquedas

Hola iPaNiiCx:

Si la consulta que pones en tu post es la que realmente necesitas, no hay necesidad de utilizar un UNION, pues la información la estás extrayendo de la misma tabla, bastaría con utilizar una sentencia IN en el WHERE para poder aplicar la comparación de múltiples materias:

Código MySQL:
Ver original
  1. mysql> SELECT profesor.nombre, curso.nombre
  2.     -> FROM profesor INNER JOIN curso ON profesor.noEmp = curso.noEmp
  3.     -> WHERE
  4.     -> curso.nombre IN ('Matemáticas', 'Inglés');
  5. +--------------------+-------------+
  6. | nombre             | nombre      |
  7. +--------------------+-------------+
  8. | Liliana Valenzuela | Matemáticas |
  9. | Erika Lopez        | Inglés      |
  10. +--------------------+-------------+
  11. 2 rows in set (0.00 sec)

Y algunas observaciones adicionales, no es recomendable que utilices JOIN's sin especificar la cláusula ON o USING, ya que se realiza un producto cartesiano, en tu caso estás filtrando la información en el WHERE, pero esta filtración se realiza después de hacer el producto cartesiano, lo que puede afectar mucho el rendimiento de tus consultas. Checa este ejemplo para ver la diferencia:

Código MySQL:
Ver original
  1. mysql> CREATE TABLE profesor (noEmp INT, nombre VARCHAR(20));
  2. Query OK, 0 rows affected (0.12 sec)
  3.  
  4. mysql> INSERT INTO profesor VALUES (1, 'Liliana Valenzuela'),
  5.     -> (2, 'Erika Lopez'), (3, 'Fulano de tal');
  6. Query OK, 3 rows affected (0.03 sec)
  7. Records: 3  Duplicates: 0  Warnings: 0
  8.  
  9. mysql> SELECT * FROM profesor;
  10. +-------+--------------------+
  11. | noEmp | nombre             |
  12. +-------+--------------------+
  13. |     1 | Liliana Valenzuela |
  14. |     2 | Erika Lopez        |
  15. |     3 | Fulano de tal      |
  16. +-------+--------------------+
  17. 3 rows in set (0.00 sec)
  18.  
  19. mysql> CREATE TABLE curso (noCurso INT, noEmp INT, nombre VARCHAR(20));
  20. Query OK, 0 rows affected (0.11 sec)
  21.  
  22. mysql> INSERT INTO curso VALUES (1, 1, 'Matemáticas'), (2, 2, 'Inglés');
  23. Query OK, 2 rows affected (0.03 sec)
  24. Records: 2  Duplicates: 0  Warnings: 0
  25.  
  26. mysql> SELECT * FROM curso;
  27. +---------+-------+-------------+
  28. | noCurso | noEmp | nombre      |
  29. +---------+-------+-------------+
  30. |       1 |     1 | Matemáticas |
  31. |       2 |     2 | Inglés      |
  32. +---------+-------+-------------+
  33. 2 rows in set (0.00 sec)
  34.  
  35. mysql> #Sin poner ON o USING se realiza un producto cartesiano antes del where
  36. mysql> SELECT * FROM profesor JOIN curso;
  37. +-------+--------------------+---------+-------+-------------+
  38. | noEmp | nombre             | noCurso | noEmp | nombre      |
  39. +-------+--------------------+---------+-------+-------------+
  40. |     1 | Liliana Valenzuela |       1 |     1 | Matemáticas |
  41. |     1 | Liliana Valenzuela |       2 |     2 | Inglés      |
  42. |     2 | Erika Lopez        |       1 |     1 | Matemáticas |
  43. |     2 | Erika Lopez        |       2 |     2 | Inglés      |
  44. |     3 | Fulano de tal      |       1 |     1 | Matemáticas |
  45. |     3 | Fulano de tal      |       2 |     2 | Inglés      |
  46. +-------+--------------------+---------+-------+-------------+
  47. 6 rows in set (0.00 sec)
  48.  
  49. mysql> SELECT * FROM profesor JOIN curso
  50.     -> WHERE profesor.noEmp = curso.noEmp;
  51. +-------+--------------------+---------+-------+-------------+
  52. | noEmp | nombre             | noCurso | noEmp | nombre      |
  53. +-------+--------------------+---------+-------+-------------+
  54. |     1 | Liliana Valenzuela |       1 |     1 | Matemáticas |
  55. |     2 | Erika Lopez        |       2 |     2 | Inglés      |
  56. +-------+--------------------+---------+-------+-------------+
  57. 2 rows in set (0.00 sec)
  58.  
  59. mysql> #Con ON o USING, la comparación se realiza directamente
  60. mysql> SELECT * FROM profesor JOIN curso ON profesor.noEmp = curso.noEmp;
  61. +-------+--------------------+---------+-------+-------------+
  62. | noEmp | nombre             | noCurso | noEmp | nombre      |
  63. +-------+--------------------+---------+-------+-------------+
  64. |     1 | Liliana Valenzuela |       1 |     1 | Matemáticas |
  65. |     2 | Erika Lopez        |       2 |     2 | Inglés      |
  66. +-------+--------------------+---------+-------+-------------+
  67. 2 rows in set (0.00 sec)

observa que aunque en las últimas dos consultas el resultado es el mismo, el primer caso no resulta óptimo. Con pocos registros no verías diferencias en los tiempos de respuesta, pero con tablas grandes verías que es mejor hacerlo con el ON.

Saludos
Leo.

Etiquetas: busquedas, restas, sumas
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 22:41.