Mostrar filas repetidas

Ya que podemos elegir sólo algunas de las columnas de una tabla, es posible que se produzcan filas repetidas, debido a que hayamos excluido las columnas únicas.

Por ejemplo, añadamos las siguientes filas a nuestra tabla:

mysql> INSERT INTO gente VALUES ('Pimplano', '1978-06-15'),
    -> ('Frutano', '1985-04-12');
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT fecha FROM gente;
+------------+
| fecha      |
+------------+
| 1985-04-12 |
| 1978-06-15 |
| 2001-12-02 |
| 1993-02-10 |
| 1978-06-15 |
| 1985-04-12 |
+------------+
6 rows in set (0.00 sec)

mysql>

Vemos que existen dos valores de filas repetidos, para la fecha "1985-04-12" y para "1978-06-15". La sentencia que hemos usado asume el valor por defecto (ALL) para el grupo de opciones ALL, DISTINCT y DISTINCTROW. En realidad sólo existen dos opciones, ya que las dos últimas: DISTINCT y DISTINCTROW son sinónimos.

La otra alternativa es usar DISTINCT, que hará que sólo se muestren las filas diferentes:

mysql> SELECT DISTINCT fecha FROM gente;
+------------+
| fecha      |
+------------+
| 1985-04-12 |
| 1978-06-15 |
| 2001-12-02 |
| 1993-02-10 |
+------------+
4 rows in set (0.00 sec)

mysql>

Limitar las filas: selección

Otra de las operaciones del álgebra relacional era la selección, que consitía en seleccionar filas de una realación que cumplieran determinadas condiciones.

Lo que es más útil de una base de datos es la posibilidad de hacer consultas en función de ciertas condiciones. Generalmente nos interesará saber qué filas se ajustan a determinados parámetros. Por supuesto, SELECT permite usar condiciones como parte de su sintaxis, es decir, para hacer selecciones. Concretamente mediante la cláusula WHERE, veamos algunos ejemplos:

mysql> SELECT * FROM gente WHERE nombre="Mengano";
+---------+------------+
| nombre  | fecha      |
+---------+------------+
| Mengano | 1978-06-15 |
+---------+------------+
1 row in set (0.03 sec)

mysql> SELECT * FROM gente WHERE fecha>="1986-01-01";
+--------+------------+
| nombre | fecha      |
+--------+------------+
| Tulano | 2001-12-02 |
| Pegano | 1993-02-10 |
+--------+------------+
2 rows in set (0.00 sec)

mysql> SELECT * FROM gente 
    -> WHERE fecha>="1986-01-01" AND fecha < "2000-01-01";
+--------+------------+
| nombre | fecha      |
+--------+------------+
| Pegano | 1993-02-10 |
+--------+------------+
1 row in set (0.00 sec)

mysql>

En una cláusula WHERE se puede usar cualquier función disponible en MySQL, excluyendo sólo las de resumen o reunión, que veremos en el siguiente punto. Esas funciones están diseñadas específicamente para usarse en cláusulas GROUP BY.

También se puede aplicar lógica booleana para crear expresiones complejas. Disponemos de los operadores AND, OR, XOR y NOT.

En próximos capítulos veremos los operadores de los que dispone MySQL.

Agrupar filas

Es posible agrupar filas en la salida de una sentencia SELECT según los distintos valores de una columna, usando la cláusula GROUP BY. Esto, en principio, puede parecer redundante, ya que podíamos hacer lo mismo usando la opción DISTINCT. Sin embargo, la cláusula GROUP BY es más potente:

mysql> SELECT fecha FROM gente GROUP BY fecha;
+------------+
| fecha      |
+------------+
| 1978-06-15 |
| 1985-04-12 |
| 1993-02-10 |
| 2001-12-02 |
+------------+
4 rows in set (0.00 sec)

mysql>

La primera diferencia que observamos es que si se usa GROUP BY la salida se ordena según los valores de la columna indicada. En este caso, las columnas aparecen ordenadas por fechas.

Otra diferencia es que se eliminan los valores duplicados aún si la proyección no contiene filas duplicadas, por ejemplo:

mysql> SELECT nombre,fecha FROM gente GROUP BY fecha;
+---------+------------+
| nombre  | fecha      |
+---------+------------+
| Mengano | 1978-06-15 |
| Fulano  | 1985-04-12 |
| Pegano  | 1993-02-10 |
| Tulano  | 2001-12-02 |
+---------+------------+
4 rows in set (0.00 sec)

mysql>

Pero la diferencia principal es que el uso de la cláusula GROUP BY permite usar funciones de resumen o reunión. Por ejemplo, la función COUNT(), que sirve para contar las filas de cada grupo:

mysql> SELECT fecha, COUNT(*) AS cuenta FROM gente GROUP BY fecha;
+------------+--------+
| fecha      | cuenta |
+------------+--------+
| 1978-06-15 |      2 |
| 1985-04-12 |      2 |
| 1993-02-10 |      1 |
| 2001-12-02 |      1 |
+------------+--------+
4 rows in set (0.00 sec)

mysql>

Esta sentencia muestra todas las fechas diferentes y el número de filas para cada fecha.

Existen otras funciones de resumen o reunión, como MAX(), MIN(), SUM(), AVG(), STD(), VARIANCE()...

Estas funciones también se pueden usar sin la cláusula GROUP BY siempre que no se proyecten otras columnas:

mysql> SELECT MAX(nombre) FROM gente;
+-------------+
| max(nombre) |
+-------------+
| Tulano      |
+-------------+
1 row in set (0.00 sec)

mysql>

Esta sentencia muestra el valor más grande de 'nombre' de la tabla 'gente', es decir, el último por orden alfabético.