El lenguaje de consulta de datos (DQL por sus siglas en inglés) es la parte de SQL que se encarga de consultar los datos en una base de datos. Está compuesto por la cláusula SELECT.
Es el comando más utilizado. Al utilizarlo, se pueden obtener los datos completos de la tabla, uno o varios registros en específico o, incluso, sólo alguno de los campos de algún registro en particular.
SELECT lista_de_campos_separados_por_coma FROM tabla [WHERE condición];
Al especificar una lista de campos, el resultado solamente mostrará dichos campos. Para mostrar todos los campos de un registro se utiliza el asterisco (*) como comodín para referirse a todos los campos.
Ejemplo:SELECT * FROM alumno;
El comando anterior mostrará todos los campos de todos los registros de la tabla alumno.SELECT nombre, direccion FROM alumno WHERE num_cuenta = 97520;
El commando anterior mostrará solamente los campos nombre y direccion de la tabla alumno para aquel registro que tenga el campo num_cuenta igual a 97520.A veces, cuando se tienen dos o más tablas relacionadas, se quiere obtener información contenida en esas tablas y se necesita especificar una cláusula con respecto a la referencia entre columnas.
Ejemplo:SELECT alumnos.nombre, adeudos.cantidad FROM alumnos,adeudos WHERE alumnos.num_cuenta = adeudos.num_cuenta;
Existen dos tipos:
- Funciones de conjunto (set o agregate functions)
- Funciones de valor (value functions)
Aplican a un conjunto de registros en una tabla. Estas funciones dan una característica de ese conjunto de registros.
Regresa el número de registros que couplen con una condición determinada.
Ejemplos:SELECT COUNT(*) FROM alumnos;
El commando anterior regresa el número de registros de una tabla.SELECT COUNT(carrera) FROM alumnos;
El comando anterior regresa el número de registros de la tabla alumnos cuyo campo carrera tenga un valor diferente de null.SELECT COUNT(DISTINCT carrera) FROM alumnos;
Regresa el número de registros únicos (no repetidos) que tengan una carrera válida, es decir, el número de carreras válidas.Regresa el valor promedio de los valores del campo especificado (sólo se aplica a campos numéricos).
Ejemplos:SELECT AVG(promedio) FROM alumnos;
Regresa el valor máximo encontrado en el campo especificado.
Ejemplos:SELECT MAX(promedio) FROM alumnos;
Regresa el valor mínimo encontrado en el campo especificado.
Ejemplos:SELECT MIN(promedio) FROM alumnos;
Regresa la sumatoria de todos los valores del campo especificado.
Ejemplos:SELECT SUM(cantidad) FROM adeudos;
Existen de tres tipos:
- Funciones de valor de cadenas
- Funciones de valor de números
- Funciones de valor de fechas y tiempos
Toman una cadena (de caracteres o de bits) como entrada y regresan otra cadena como salida. Existen seis funciones de valor de cadenas.
Extrae una subcadena de una cadena original.
SUBSTRING (cadena FROM inicio [FOR longitud])
Si no se especifica una longitud, entonces la subcadena se tomará hasta el final de la cadena.
Ejemplo:SELECT * FROM alumnos WHERE SUBSTRING(nombre FROM 1 FOR 1) = 'C';
Regresa todos los alumnos cuyo nombre empiece con 'C'. Si la cadena tiene valor nulo o si el valor de inicio de la subcadena es mayor que la longitud de la cadena original, entonces la función regresará un valor nulo.Convierte todos los caracteres de la cadena a mayúsculas.
Ejemplo:UPPER(nombre);
Convierte todos los caracteres de la cadena a minúsculas.
Ejemplo:LOWER(nombre);
Recorta del inicio o final (LEADING, TRAILING o BOTH) de la cadena el caracter especificado (pueden ser espacios en blanco o cualquier otro caracter).
Ejemplo:TRIM(BOTH ' ' FROM nombre);
Si no se especifica un caracter, entonces se toma el valor por omisión, que es el espacio en blanco.
Ejemplo:TRIM(BOTH FROM nombre);
Toman diferentes tipos de entrada pero siempre regresan un valor numérico. Existen cinco funciones de este tipo.
Busca la subcadena especificada dentro de la cadena y regresa la posición de inicio ó 0 (cero) si no se encontró.
Ejemplo:POSITION('' IN NOMBRE)
Regresa el número de caracteres en la cadena.
Ejemplo:CHARACTER_LENGTH(nombre);
Regresa el número de bytes (u octetos) necesarios para almacenar la cadena de caracteres o bits.
Ejemplo:OCTEC_LENGTH(nombre);
Regresa el número de bits de una cadena de bits.
Ejemplo:BIT_LENGTH(B'1010110100');
Extrae un valor de una fecha, de una hora o de un intervalo.
Ejemplo:EXTRACT (MONTH FROM ingreso);
Funciones de valor de fechas y tiempos
Son tres funciones:
CURRENT_DATE(): Regresa la fecha actual.
CURRENT_TIME(): Regresa la hora actual. CURRENT_TIMESTAMP(): Regresa la fecha y hora actual. A las funciones:CURRENT_TIME y CURRENT_TIMESTAMP se les puede especificar el número de dígitos para la parte fraccionaria de los segundos.Pueden contener valores literales, nombres de campos, variables, sub-búsquedas, operadores lógicos o aritméticos, o, incluso, otras expresiones, pero siempre deberán reducirse a un valor único.
Como operadores aritméticos existen la suma ( + ), resta ( - ), la multiplicaión ( * ) y la división ( / ). Los operadores pueden ser de distintos tipos con tal de que todos sean numéricos. El tipo del resultado depende de la implementación.
Para cadenas existe el operador para la concatenación ( || ).
Para fechas y tiempos e intervalos, se pueden:
- Restar dos fechas para dar un intervalo.
Ejemplo:(CURRENT_DATE - cumpleaÒos) YEARS TO MONTH
- Sumar o restar dos intervalos que dan otro intervalo
Ejemplo:INTERVAL '17' DAY + INTERVAL '23' DAY
- Multiplicar o dividir un intervalo y un número
Ejemplo:INTERVAL '9' MONTH * 5
A diferencia de otros lenguajes, el enunciado CASE en SQL es una expresión que se evalúa a un valor, en lugar de un bloque de enunciados que se ejecutan.
Su estructura es:
CASE
WHEN condición1 THEN valor1
WHEN condicion2 THEN valor2
...
WHEN condicionN THEN valorN
ELSE
valorX
END;Ejemplo:
UPDATE alumnos
SET inicio = CASE
WHEN num_cuenta < 90000 THEN '1990-08-01'
WHEN num_cuenta < 95000 THEN '1995-08-01'
WHEN num_cuenta < 100000 THEN '2000-08-01'
ELSE
'2005-08-01'
END;
Otro uso del CASE es el siguiente:
SELECT CASE carrera
WHEN 2301 THEN 'Ing.'
WHEN 2305 THEN 'Lic.'
ELSE ''
END,
nombre FROM alumno;
A veces se requiere reemplazar valores conocidos por un valor nulo. Para ello existe la forma abreviada NULLIF.
Ejemplo:UPDATE alumno
SET carrera = CASE carrera
WHEN -1 THEN NULL
ELSE carrera
END;
UPDATE alumno
SET carrera = NULLIF (carrera,-1);
También existe COALESCE que trata una lista de valores y toma el primer valor no nulo de dicha lista. Por ejemplo:
CASE
WHEN valor1 IS NOT NULL THEN valor1
WHEN valor2 IS NOT NULL THEN valor2
...
WHEN valorN IS NOT NULL THEN valorN
[ELSE NULL]
END;corresponde a:
COALESCE (valor1, valor2,..., valorN)
La expresión CAST convierte valores de un tipo de datos a otro. Obviamente existen restricciones en cuanto a las conversiones posibles.
- Cadenas de caracteres a cualquier otro tipo, con tal de que la cadena contenga un valor literal válido del otro tipo
- Cualquier tipo de valor a una cadena de caracteres
- Cualquier tipo numérico a otro tipo numérico. en caso de que se convierta un número con menor parte fraccional, el sistema trunca el resultado
- Numéricos exactos a intervalos
- Fechas (DATE) a TIMESTAMP, con la parte del tiempo en ceros
- Tiempos (TIME) a TIMESTAMP, con la parte de la fecha en ceros
- TIMESTAMP a fechas (DATE) o tiempos (TIME
- Cualquier intervalo a un numérico exacto
La sintaxis es la siguiente:
CAST (campo AS tipo)
Expresiones de Valor de Registros
Operan sobre una lista de valores en lugar de valores únicos. Es una lista de valores entre paréntesis y separados por comas.
Por ejemplo, el siguiente query:
SELECT * FROM alumno WHERE
carrera = 2301 AND pais = 'Mexico' AND sexo = 'Masculino';es equivalente a:
SELECT * FROM alumno WHERE
(carrera, pais,sexo) = (2301,'Mexico','Masculino');La ventaja de usar expresiones de valor de registro es que son más eficientes (más rápidas).
Los modificadores de cláusulas son:
FROM: Especifica las tablas a utilizar
WHERE: Filtra los registros que no cumplan con la condición de búsqueda HAVING: Separa los registros en grupos GROUP BY: Filtra los grupos que no cumplan con la condición de búsqueda ORDER BY: Ordena los resultados SELECT lista_campos
FROM lista_tabla
[WHERE condición_de_búsqueda]
[GROUP BY campo]
[HAVING condición_de_búsqueda]
[ORDER BY condición_de_ordenamiento]
La cláusula FROM se utiliza para especificar las tablas sobre las cuales se va a hacer la selección de datos. Pueden ser una o más tablas. En el caso de varias tablas, la operación arroja el producto cartesiano de esas tablas. Por ejemplo, si se hace un SELECT de dos tablas, una con 5 registros y la otra con 6 registros, se obtiene como resultado 30 registros con la combinación de registros de una y otra tabla. Para obtener sólo aquellos registros útiles se deberá filtrar la consulta con el uso de la cláusula WHERE.
Un comando solamente opera sobre aquellos registros que cumplan con la condición WHERE. Una condición puede ser verdadera, falsa o desconocida. …sta última resulta cuando alguno de los elementos es nulo. Se pueden utilizar los conectivos lógicos AND, OR y NOT para unir múltiples condiciones. Las condiciones que expresan estas cláusulas WHERE se conocen como predicados.
Existen los siguientes tipos de predicados:
- Comparativos
- BETWEEN
- IN
- LIKE
- NULL
- ALL, SOME, ANY
- EXISTS
- UNIQUE
- OVERLAPS
- MATCH
- Lógicos
Son los más comunes y son los siguientes:
- Igual - =
- Diferente - <>
- Menor que - <
- Mayor que - >
- Menor o igual - <=
- Mayor o igual - >=
En ocasiones se requiere especificar un rango de valores y una manera de hacerlo es con predicados comparativos.
Ejemplo:SELECT * FORM alumnos WHERE edad >= 18 AND edad <=25;
Otra forma de hacerlo es con el predicado BETWEEN:
SELECT * FROM alumnos WHERE edad BETWEEN 18 AND 25;
Es importante seÒalar que el BETWEEN sólo es para rangos que incluyan los valores límites (límites cerrados) y que el primer valor especificado debe ser menor o igual que el segundo valor.
Especifica que un valor en determinado se debe encontrar dentro de un grupo definido de valores.
Ejemplo:SELECT * FROM alumnos WHERE carrera IN (2301, 2302, 2303);
Que sería equivalente a:
SELECT * FROM alumnos WHERE
carrera = 2301 OR carrera = 2302 OR carrera = 2303;La gran utilidad de este predicado es cuando se combina con otro comando:
SELECT * FROM alumnos
WHERE carrera IN (SELECT id_carrera FROM carreras
WHERE departamento = 'IME');Se utiliza para comparar dos cadenas buscando una coincidencia parcial. Utiliza dos caracteres especiales:
% - que representa cualquier cadena de caracteres con una longitud de cero o más caracteres
_ - que representa cualquier caracter Ejemplo: SELECT * FROM alumnos
WHERE nombre LIKE 'Pedro%';El query anterior regresará todos los alumnos cuyo nombre empiece con 'Pedro'.
SELECT * FROM alumnos
WHERE nombre LIKE '_arla';El query anterior regresará todos los alumnos cuyo nombre sea: 'Karla', 'Carla', 'Darla', etc.
En el caso de que se quiera buscar una cadena que contenga uno de los caracteres especiales, se debe utilizar un caracter de escape (cualquiera) de la siguiente manera:
SELECT * FROM alumnos
WHERE porcentaje LIKE '20#%%' ESCAPE '#';Regresa todos los valores que sean nulos dentro del campo especificado.
Ejemplo:SELECT * FROM alumnos WHERE carrera IS NULL;
que es diferente a:
SELECT * FROM alumnos WHERE carrera = NULL
ya que esta última condición siempre tendrá por resultado un valor desconocido.
Son parecidos a IN en cuanto a que operan sobre un conjunto de valores. ALL considera la condición como verdadera si el valor cumple con la condición con todos los valores del conjunto. SOME y ANY son sinónimos y, a diferencia de ALL, considera la condición como verdadera si el valor comple con la condición con al menos uno de los valores del conjunto.
Ejemplo:SELECT * FROM alumnos
WHERE carrera = 2301 AND promedio >
ALL (SELECT promedio FROM alumnos
WHERE carrera = 2302);El query anterior regresa aquellos alumnos de la carrera 2301 cuyo promedio sea mayor que el promedio de cada uno de los alumnos de la carrera 2302.
SELECT * FROM alumnos
WHERE carrera = 2301 AND promedio >
ANY (SELECT promedio FROM alumnos
WHERE carrera = 2302);El query anterior regresa aquellos alumnos de la carrera 2301 cuyo promedio sea mayor que el promedio de por lo menos uno de los alumnos de la carrera 2302.
Se utiliza con una sub-búsqueda para determinar si la sub-búsqueda regresa algún valor, es decir, la condición es verdadera si la sub-búsqueda regresa al menos un valor.
Ejemplo:SELECT * FROM alumnos
WHERE EXISTS(SELECT DISTINCT num_cuenta FROM adeudos);El query anterior regresa todos los alumnos que aparezcan en la tabla de adeudos y es equivalente a:
SELECT * FROM alumnos
WHERE 0 <> (SELECT COUNT(*) FROM adeudos
WHERE adeudos.num_cuenta = alumnos.num_cuenta);Es similar a EXISTS, sin embargo, con UNIQUE solamente se considera como verdadera la condición cuando la sub-búsqueda regresa un sólo valor.
Ejemplo:SELECT * FROM alumnos
WHERE UNIQUE (SELECT num_cuenta FROM adeudos
WHERE adeudos.num_cuenta = alumnos.num_cuenta);
El query anterior regresa solamente los alumnos que tengan un sólo adeudo.
Se utiliza para determinar si dos intervalos de tiempo se sobreponen
Ejemplo:(TIME '20:00:00', INTERVAL '2' HOUR)
OVERLAPS
(TIME '18:30:00', TIME '20:30:00' )
La instrucción anterior regresa un valor verdadero, ya que los intervalos se sobreponen.
(TIME '18:00:00', TIME '20:00:00')
OVERLAPS
(TIME '20:00:00', TIME '22:00:00' )
La instrucción anterior regresa un valor falso, ya que los intervalos son contínuos y no se sobreponen.
Verifica que coincidan los valores (aunque algunos valores pueden ser nulos).
Ejemplo:SELECT * FROM alumnos
WHERE (96491, 'Biblioteca')
MATCH (SELECT num_cuenta, tipo FROM adeudos);Este predicado es útil para verificar la integridad referencial.
En ocasiones es necesario combinar dos o más condiciones u obtener el resultado contrario de la condición. Para ello se utilizan AND, OR y NOT. Se pueden utilizar paréntesis para hacer la condición más clara.
Filtra los registros obtenidos de un GROUP BY. La condición de HAVING debe comparar un valor del campo que se agrupa con un valor constante.
Ejemplo:SELECT * FROM alumnos
GROUP BY carrera
HAVING carrera = 2301;Al realizar un SELECT, los registros aparecen en el mismo orden en el que fueron insertados en la tabla. Si se quiere que aparezcan en otro orden se utiliza la cláusula GROUP BY, especificando uno o más campos con los cuales se llevará a cabo el agrupamiento (registros con valores iguales aparecen juntos y ordena alfabéticamente los grupos).
Ejemplo:SELECT * FROM alumnos GROUP BY carrera;
Ordena los campos especificados en orden alfabético de manera ascendente (valor por omisión) o descendente. Cuando son dos o más campos, primero ordena el primer campo, luego el segundo y así sucesivamente. En el caso de que también haya un GROUP BY en la consulta, primero agrupa y luego ordena los campos dentro de cada grupo. El ORDER BY debe ser la última cláusula dentro de una consulta.
Ejemplo:SELECT * FROM alumnos
ORDER BY carrera DESC, apellido ASC, nombre;El query anterior regresa todos los alumnos ordenados por carrera de manera descendente (de mayor a menor), por apellido de manera ascendente y por nombre de manera ascendente.
Estos operadores sirven para poder relacionar dos tablas de una base de datos.
Este operador es útil cuando se quiere unir los resultados de más de un query. Hay que tener cuidado de que el número de columnas regresadas de cada query sea igual.
Ejemplo:SELECT campo1, campo2, ..., campoN FROM tabla1
UNION
SELECT campo1, campo2, ..., campoN FROM tabla2;
UNION ALL funciona de la misma manera que UNION, con la diferencia de que regresará todos los valores de ambas tablas, inclusive los repetidos.
Se puede utilzar la directiva INTERSEC para generar una intersección de los valores resultantes de dos queries.
Ejemplo:SELECT campo1, campo2, ..., campoN FROM tabla1
INTERSECT
SELECT campo1, campo2, ..., campoN FROM tabla2
Si no se especifica explícitamente un ALL, automáticamente SQL ejecutará un DISTINCT en este query.
Se puede utilizar la cláusula EXCEPT para eliminar los renglones del resultado de un query que resulten de un segundo query.
Ejemplo:SELECT campo1, campo2, ..., campoN FROM tabla1
EXCEPT
SELECT campo1, campo2, ..., campoN FROM tabla2
El query anterior desplegará sólo los campos de tabla1 que no existan en la tabla2.
La directiva JOIN se puede utilizar para unir solo una parte o toda la información de dos o más tablas en una sóla estructura. Existen varios tipos de JOIN:
CROSS-JOIN: Es un tipo muy básico para relacionar dos tablas. Simplemente relaciona cada uno de los renglones de la primera tabla con cada uno de los renglones de la segunda tabla. El número de renglones resultantes de este tipo de queries será igual al producto cartesiano de los renglones de las tablas involucradas.
EQUI-JOIN: Se utiliza cuando algunos valores contenidos en una tabla corresponden a valores contenidos en otra u otras tablas. Este tipo de acciones se realiza al utilizar un WHERE en la cláusula SELECT. OUTER JOIN: Se utiliza para obtener información con base en ciertas restricciones. LEFT JOIN
RIGHT JOIN FULL JOIN NATURAL JOIN:
SELECT * FROM tabla1 NATURAL JOIN tabla2CONDITION JOIN: No se busca igualdad (puede ser).
SELECT * FROM tabla1 JOIN tabla2 ON condicionCOLUMN-NAME JOIN:
SELECT * FROM tabla1 JOIN tabla2 USING (lista_de_campos)