Lenguaje de Consulta de Datos (DQL)

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.

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.

Referencias a columnas

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;

Funciones

Existen dos tipos:

  • Funciones de conjunto (set o agregate functions)
  • Funciones de valor (value functions)

Funciones de conjunto

Aplican a un conjunto de registros en una tabla. Estas funciones dan una característica de ese conjunto de registros.

COUNT

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.

AVG

Regresa el valor promedio de los valores del campo especificado (sólo se aplica a campos numéricos).

Ejemplos:

SELECT AVG(promedio) FROM alumnos;

MAX

Regresa el valor máximo encontrado en el campo especificado.

Ejemplos:

SELECT MAX(promedio) FROM alumnos;

MIN

Regresa el valor mínimo encontrado en el campo especificado.

Ejemplos:

SELECT MIN(promedio) FROM alumnos;

SUM

Regresa la sumatoria de todos los valores del campo especificado.

Ejemplos:

SELECT SUM(cantidad) FROM adeudos;

Funciones de valor

Existen de tres tipos:

  • Funciones de valor de cadenas
  • Funciones de valor de números
  • Funciones de valor de fechas y tiempos

Funciones de valor de cadenas

Toman una cadena (de caracteres o de bits) como entrada y regresan otra cadena como salida. Existen seis funciones de valor de cadenas.

SUBSTRING

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.

UPPER

Convierte todos los caracteres de la cadena a mayúsculas.

Ejemplo:

UPPER(nombre);

LOWER

Convierte todos los caracteres de la cadena a minúsculas.

Ejemplo:

LOWER(nombre);

TRIM

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);

Funciones de valor de números

Toman diferentes tipos de entrada pero siempre regresan un valor numérico. Existen cinco funciones de este tipo.

POSITION

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)

CHARACTER_LENGTH

Regresa el número de caracteres en la cadena.

Ejemplo:

CHARACTER_LENGTH(nombre);

OCTET_LENGTH

Regresa el número de bytes (u octetos) necesarios para almacenar la cadena de caracteres o bits.

Ejemplo:

OCTEC_LENGTH(nombre);

BIT_LENGTH

Regresa el número de bits de una cadena de bits.

Ejemplo:

BIT_LENGTH(B'1010110100');

EXTRACT

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.

Expresiones de valor

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.

Operadores

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

Expresiones condicionales

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;

Casos especiales

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)

Conversiones de tipos

La expresión CAST convierte valores de un tipo de datos a otro. Obviamente existen restricciones en cuanto a las conversiones posibles.

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).

Modificadores de cláusula

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]

Cláusula FROM

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.

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

Comparativos

Son los más comunes y son los siguientes:
  • Igual -     =
  • Diferente -     <>
  • Menor que -     <
  • Mayor que -     >
  • Menor o igual -     <=
  • Mayor o igual -     >=

BETWEEN

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.

IN

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');

LIKE

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 '#';

NULL

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.

ALL, SOME, ANY

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.

EXISTS

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);

UNIQUE

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.

OVERLAPS

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.

MATCH

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.

Lógicos

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.

Cláusula HAVING

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;

Cláusula GROUP BY

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;

Cláusula ORDER BY

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.

Operadores Relacionales

Estos operadores sirven para poder relacionar dos tablas de una base de datos.

UNION

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

UNION ALL funciona de la misma manera que UNION, con la diferencia de que regresará todos los valores de ambas tablas, inclusive los repetidos.

INTERSEC

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.

EXCEPT

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.

JOIN

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 tabla2
  • CONDITION JOIN: No se busca igualdad (puede ser).
        
    SELECT * FROM tabla1 JOIN tabla2 ON condicion
  • COLUMN-NAME JOIN:
        
    SELECT * FROM tabla1 JOIN tabla2 USING (lista_de_campos)