MySQL
SELECCIONAR
Buscar..
Introducción
SELECT
se utiliza para recuperar filas seleccionadas de una o más tablas.
Sintaxis
SELECCIONAR DISTINTO [expresiones] DE TableName [DÓNDE condiciones]; /// Selección simple
SELECT DISTINCT (a), b ... es lo mismo que SELECT DISTINCT a, b ...
SELECCIONAR [TODO | DISTINCIÓN | DISTINCTROW] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT | SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] expresiones DE las tablas [DÓNDE condiciones] [GRUPO POR expresiones] [QUE HAYA condición] [ORDEN POR expresión [ASC | DESC]] [LIMIT [offset_value] number_rows | LIMIT number_rows OFFSET offset_value] [PROCEDIMIENTO procedure_name] [INTO [OUTFILE 'file_name' opciones | DUMPFILE 'nombre_archivo' | @ variable1, @ variable2, ... @variable_n] [PARA ACTUALIZAR | BLOQUEO EN MODO COMPARTIDO]; /// Sintaxis de selección completa
Observaciones
Para obtener más información sobre la instrucción SELECT
de MySQL, consulte MySQL Docs .
SELECCIONAR por nombre de columna
CREATE TABLE stack(
id INT,
username VARCHAR(30) NOT NULL,
password VARCHAR(30) NOT NULL
);
INSERT INTO stack (`id`, `username`, `password`) VALUES (1, 'Foo', 'hiddenGem');
INSERT INTO stack (`id`, `username`, `password`) VALUES (2, 'Baa', 'verySecret');
Consulta
SELECT id FROM stack;
Resultado
+------+
| id |
+------+
| 1 |
| 2 |
+------+
SELECCIONAR todas las columnas (*)
Consulta
SELECT * FROM stack;
Resultado
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | admin | admin |
| 2 | stack | stack |
+------+----------+----------+
2 rows in set (0.00 sec)
Puede seleccionar todas las columnas de una tabla en una combinación haciendo:
SELECT stack.* FROM stack JOIN Overflow ON stack.id = Overflow.id;
Práctica recomendada No utilice *
menos que esté depurando o recuperando la (s) fila (s) en matrices asociativas, de lo contrario los cambios de esquema (AGREGAR / DROPAR / reorganizar columnas) pueden provocar errores de aplicación desagradables. Además, si proporciona la lista de columnas que necesita en su conjunto de resultados, el planificador de consultas de MySQL a menudo puede optimizar la consulta.
Pros:
- Cuando agrega / elimina columnas, no tiene que hacer cambios donde usó
SELECT *
- Es mas corto para escribir
- También ve las respuestas, ¿entonces el uso de
SELECT *
puede justificarse alguna vez?
Contras:
- Usted está devolviendo más datos de los que necesita. Supongamos que agrega una columna VARBINARY que contiene 200k por fila. Solo necesita estos datos en un solo lugar para un solo registro: con
SELECT *
puede terminar devolviendo 2MB por 10 filas que no necesita - Explícito sobre qué datos se utilizan
- Especificar columnas significa que recibe un error cuando se elimina una columna
- El procesador de consultas tiene que hacer un poco más de trabajo: averiguar qué columnas existen en la tabla (gracias @vinodadhikary)
- Puedes encontrar donde se usa una columna más fácilmente
- Obtiene todas las columnas en uniones si usa SELECT *
- No se pueden usar referencias ordinales de manera segura (aunque usar referencias ordinales para columnas es una mala práctica en sí misma)
- En consultas complejas con campos de
TEXT
, la consulta puede verse ralentizada por un procesamiento de la tabla temporal menos óptimo
SELECCIONA con DONDE
Consulta
SELECT * FROM stack WHERE username = "admin" AND password = "admin";
Resultado
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | admin | admin |
+------+----------+----------+
1 row in set (0.00 sec)
Consulta con un SELECT anidado en la cláusula WHERE
La cláusula WHERE
puede contener cualquier instrucción SELECT
válida para escribir consultas más complejas. Esta es una consulta 'anidada'
Consulta
Las consultas anidadas se utilizan generalmente para devolver valores atómicos únicos de las consultas para las comparaciones.
SELECT title FROM books WHERE author_id = (SELECT id FROM authors WHERE last_name = 'Bar' AND first_name = 'Foo');
Selecciona todos los nombres de usuario sin dirección de correo electrónico
SELECT * FROM stack WHERE username IN (SELECT username FROM signups WHERE email IS NULL);
Descargo de responsabilidad: considere la posibilidad de utilizar uniones para mejorar el rendimiento al comparar un conjunto de resultados completo.
SELECCIONAR con LIKE (%)
CREATE TABLE stack
( id int AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(100) NOT NULL
);
INSERT stack(username) VALUES
('admin'),('k admin'),('adm'),('a adm b'),('b XadmY c'), ('adm now'), ('not here');
"adm" en cualquier lugar:
SELECT * FROM stack WHERE username LIKE "%adm%";
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 2 | k admin |
| 3 | adm |
| 4 | a adm b |
| 5 | b XadmY c |
| 6 | adm now |
+----+-----------+
Comienza con "adm":
SELECT * FROM stack WHERE username LIKE "adm%";
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
| 3 | adm |
| 6 | adm now |
+----+----------+
Termina con "adm":
SELECT * FROM stack WHERE username LIKE "%adm";
+----+----------+
| id | username |
+----+----------+
| 3 | adm |
+----+----------+
Al igual que el carácter %
en una cláusula LIKE
coincide con cualquier número de caracteres, el carácter _
solo coincide con un carácter. Por ejemplo,
SELECT * FROM stack WHERE username LIKE "adm_n";
+----+----------+
| id | username |
+----+----------+
| 1 | admin |
+----+----------+
Notas de rendimiento Si hay un índice en el username
de username
, entonces
-
LIKE 'adm'
realiza lo mismo que `= 'adm' -
LIKE 'adm%
es un "rango", similar aBETWEEN..AND..
Puede hacer un buen uso de un índice en la columna. -
LIKE '%adm'
(o cualquier variante con un comodín líder) no pueden utilizar cualquier índice. Por lo tanto será lento. En tablas con muchas filas, es probable que sea tan lento que sea inútil. -
RLIKE
(REGEXP
) tiende a ser más lento queLIKE
, pero tiene más capacidades. - Mientras que MySQL ofrece la indexación
FULLTEXT
en muchos tipos de tablas y columnas, esos índicesFULLTEXT
no se usan para cumplir las consultas que usanLIKE
.
SELECCIONAR con Alias (AS)
Los alias de SQL se utilizan para cambiar temporalmente el nombre de una tabla o una columna. Generalmente se utilizan para mejorar la legibilidad.
Consulta
SELECT username AS val FROM stack;
SELECT username val FROM stack;
(Nota: AS
es sintácticamente opcional.)
Resultado
+-------+
| val |
+-------+
| admin |
| stack |
+-------+
2 rows in set (0.00 sec)
SELECT con una cláusula LIMIT
Consulta:
SELECT *
FROM Customers
ORDER BY CustomerID
LIMIT 3;
Resultado:
Identificación del cliente | Nombre del cliente | Nombre de contacto | Dirección | Ciudad | Código postal | País |
---|---|---|---|---|---|---|
1 | Alfreds Futterkiste | Maria anders | Obere Str. 57 | Berlina | 12209 | Alemania |
2 | Ana Trujillo Emparedados Y Helados | Ana trujillo | Avda. de la Constitución 2222 | México DF | 05021 | Méjico |
3 | Taquería antonio moreno | Antonio moreno | Mataderos 2312 | México DF | 05023 | Méjico |
Mejores Prácticas Siempre use ORDER BY
al usar LIMIT
; De lo contrario, las filas que obtendrá serán impredecibles.
Consulta:
SELECT *
FROM Customers
ORDER BY CustomerID
LIMIT 2,1;
Explicación:
Cuando una cláusula LIMIT
contiene dos números, se interpreta como LIMIT offset,count
. Entonces, en este ejemplo, la consulta salta dos registros y devuelve uno.
Resultado:
Identificación del cliente | Nombre del cliente | Nombre de contacto | Dirección | Ciudad | Código postal | País |
---|---|---|---|---|---|---|
3 | Taquería antonio moreno | Antonio moreno | Mataderos 2312 | México DF | 05023 | Méjico |
Nota:
Los valores en las cláusulas LIMIT
deben ser constantes; pueden no ser valores de columna.
SELECCIONAR con DISTINTO
La cláusula DISTINCT
después de SELECT
elimina filas duplicadas del conjunto de resultados.
CREATE TABLE `car`
( `car_id` INT UNSIGNED NOT NULL PRIMARY KEY,
`name` VARCHAR(20),
`price` DECIMAL(8,2)
);
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (1, 'Audi A1', '20000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (2, 'Audi A1', '15000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (3, 'Audi A2', '40000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (4, 'Audi A2', '40000');
SELECT DISTINCT `name`, `price` FROM CAR;
+---------+----------+
| name | price |
+---------+----------+
| Audi A1 | 20000.00 |
| Audi A1 | 15000.00 |
| Audi A2 | 40000.00 |
+---------+----------+
DISTINCT
funciona en todas las columnas para entregar los resultados, no columnas individuales. Este último es a menudo una idea falsa de los nuevos desarrolladores de SQL. En resumen, lo que importa es la distinción en el nivel de fila del conjunto de resultados, no la distinción en el nivel de columna. Para visualizar esto, mire "Audi A1" en el conjunto de resultados anterior.
Para versiones posteriores de MySQL, DISTINCT
tiene implicaciones con su uso junto con ORDER BY
. La configuración para ONLY_FULL_GROUP_BY
entra en juego como se ve en la siguiente página del Manual de MySQL titulada Manejo de MySQL de GROUP BY .
SELECCIONAR con LIKE (_)
Un carácter _
en un patrón de cláusula LIKE
coincide con un solo carácter.
Consulta
SELECT username FROM users WHERE users LIKE 'admin_';
Resultado
+----------+
| username |
+----------+
| admin1 |
| admin2 |
| admin- |
| adminA |
+----------+
SELECCIONAR con CASO o SI
Consulta
SELECT st.name,
st.percentage,
CASE WHEN st.percentage >= 35 THEN 'Pass' ELSE 'Fail' END AS `Remark`
FROM student AS st ;
Resultado
+--------------------------------+
| name | percentage | Remark |
+--------------------------------+
| Isha | 67 | Pass |
| Rucha | 28 | Fail |
| Het | 35 | Pass |
| Ansh | 92 | Pass |
+--------------------------------+
O con si
SELECT st.name,
st.percentage,
IF(st.percentage >= 35, 'Pass', 'Fail') AS `Remark`
FROM student AS st ;
nótese bien
IF(st.percentage >= 35, 'Pass', 'Fail')
Esto significa que: SI st.percentage> = 35 es TRUE luego devuelva
'Pass'
ELSE return'Fail'
SELECCIONAR CON ENTRE
Puede usar la cláusula BETWEEN para reemplazar una combinación de condiciones "mayores que iguales Y menores que iguales".
Datos
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 2 | root |
| 3 | toor |
| 4 | mysql |
| 5 | thanks |
| 6 | java |
+----+-----------+
Consulta con operadores.
SELECT * FROM stack WHERE id >= 2 and id <= 5;
Consulta similar con BETWEEN
SELECT * FROM stack WHERE id BETWEEN 2 and 5;
Resultado
+----+-----------+
| id | username |
+----+-----------+
| 2 | root |
| 3 | toor |
| 4 | mysql |
| 5 | thanks |
+----+-----------+
4 rows in set (0.00 sec)
Nota
BETWEEN usa
>=
y<=
, no>
y<
.
Usando NO ENTRE
Si quieres usar el negativo puedes usar NOT
. Por ejemplo :
SELECT * FROM stack WHERE id NOT BETWEEN 2 and 5;
Resultado
+----+-----------+
| id | username |
+----+-----------+
| 1 | admin |
| 6 | java |
+----+-----------+
2 rows in set (0.00 sec)
Nota
NO ENTRE utiliza
>
y<
y no>=
y<=
Es decir,WHERE id NOT BETWEEN 2 and 5
es lo mismo queWHERE (id < 2 OR id > 5)
.
Si tiene un índice en una columna que usa en una BETWEEN
search, MySQL puede usar ese índice para una exploración de rango.
SELECCIONAR con rango de fechas
SELECT ... WHERE dt >= '2017-02-01'
AND dt < '2017-02-01' + INTERVAL 1 MONTH
Claro, esto podría hacerse con BETWEEN
e inclusión de 23:59:59
. Pero, el patrón tiene estos beneficios:
- No tiene un cálculo previo de la fecha de finalización (que a menudo es una longitud exacta desde el inicio)
- No incluye ambos puntos finales (como lo hace
BETWEEN
), ni escriba '23: 59: 59 'para evitarlo. - Funciona para
DATE
,TIMESTAMP
,DATETIME
e incluso elDATETIME(6)
incluido en el microsegundoDATETIME(6)
. - Se ocupa de los días bisiesto, fin de año, etc.
- Es fácil de indexar (también lo es
BETWEEN
).