Consultas SQL (DML)
SQL (Structured Query Language) es el lenguaje de interrogación y manipulación de bases de datos relacionales. Es el estándar de facto cuando hablamos de lenguajes de interrogación de bases de datos y su base es el álgebra relacional. Fue normalizado por ANSI/ISO (ISO/IEC 9075), con hitos como SQL-86, SQL-89 y SQL-92 (SQL2), y es hoy el lenguaje de manipulación de datos más utilizado en la actualidad.
Además de SQL existen otros lenguajes de manipulación de datos (DML, Data Manipulation Language) históricos de modelos pre-relacionales: IMS/DL1 (modelo jerárquico de IBM, Data Language One) y CODASYL (modelo en red/DBTG). El objetivo del DML es consultar y modificar los datos de la base de datos. En SQL, los comandos DML son SELECT, INSERT, UPDATE y DELETE (p. ej., INSERT es un comando DML); no debe confundirse con DDL (CREATE, ALTER, DROP) ni DCL (GRANT, REVOKE).
La sentencia SELECT y el orden de las cláusulas
Una consulta se estructura con cláusulas que deben escribirse en un orden fijo:
SELECT columnas
FROM tabla
WHERE condición
GROUP BY columnas
HAVING condición_de_grupo
ORDER BY columnas ASC|DESC
La cláusula ORDER BY va después de WHERE, GROUP BY y HAVING, y ordena los resultados en función de una o más columnas: su formato es ORDER BY nombrecolumna ASC|DESC (ascendente por defecto). Si se indican varias columnas, se ordena por la primera y, dentro de sus grupos, por la siguiente; el modificador ASC|DESC aplica a cada columna por separado. Así, ORDER BY Provincia DESC, Municipio ordena descendente por Provincia y, dentro de cada provincia, ascendente por Municipio (ASC es el valor por defecto).
La cláusula LIMIT (MySQL/PostgreSQL) limita el número de filas mostradas en el resultado.
WHERE frente a HAVING
Ambas eliminan datos no deseados del informe, pero actúan en momentos distintos del procesamiento:
-
WHERE filtra filas individuales antes de la agrupación (se usa con la selección de columnas y no admite funciones de agregación).
-
HAVING filtra grupos después de aplicar
GROUP BY(se usa con funciones de agregación). La cláusula HAVING solo se puede utilizar con datos agrupados y se emplea habitualmente en combinación conGROUP BY.
GROUP BY y funciones de agregación
GROUP BY agrupa varias filas en una sola por el valor de una o más columnas. Las funciones de agregación del estándar son COUNT, MAX, MIN, AVG y SUM (GROUP BY no es una función de agregación, es una cláusula). Ejemplos habituales:
-
SELECT departamento, COUNT(*) FROM empleados GROUP BY departamento HAVING COUNT(*) > 4;→ devuelve los departamentos con más de cuatro empleados. -
SELECT idArticulo, COUNT(*) FROM Articulo GROUP BY idArticulo HAVING COUNT(*) > 1→ localiza identificadores duplicados. -
SELECT COUNT(DISTINCT NOMBRE) FROM PERSONAS→ cuenta los nombres distintos (COUNT cuenta filas; DISTINCT elimina repetidos).
Operaciones JOIN
Un JOIN combina filas de dos o más tablas basándose en una columna relacionada, indicada con el operador ON. Según el estándar ANSI-SQL, los tipos de cláusula JOIN son: INNER, LEFT / RIGHT / FULL [OUTER] y CROSS (INSIDE no es un tipo válido de JOIN). El JOIN a secas equivale a INNER JOIN.
| Tipo | Comportamiento |
|---|---|
| INNER JOIN | Solo las filas con correspondencia en ambas tablas (intersección). |
| LEFT [OUTER] JOIN | Todas las de la tabla izquierda + coincidentes de la derecha; sin match, NULL en la derecha. |
| RIGHT [OUTER] JOIN | Todas las de la tabla derecha + coincidentes de la izquierda. |
| FULL [OUTER] JOIN | Todas las filas de ambas tablas, existan o no coincidencias, usando NULL como valor por defecto donde no hay match. |
| CROSS JOIN | Producto cartesiano: cada fila de una con cada fila de la otra. |
A diferencia del INNER JOIN (intersección respetada por ambas), con LEFT JOIN se da prioridad a la tabla izquierda y se busca en la derecha; con RIGHT JOIN, prioridad a la derecha buscando en la izquierda. Si en un LEFT JOIN un cliente no tiene pedidos, aparecerá igualmente con valores nulos en las columnas de pedidos. Un CROSS JOIN entre tablas de 4 y 3 filas produce 12 filas (4 × 3). Una auto-unión (self-join) une una tabla consigo misma (típicamente mediante un INNER JOIN con alias distintos) para relacionar filas de la propia tabla, como asociar cada trabajador con el nombre de su director.
Sintaxis de referencia:
SELECT * FROM tabla1 JOIN tabla2 ON tabla1.id = tabla2.id -- INNER
SELECT * FROM tabla1 LEFT JOIN tabla2 ON tabla1.col = tabla2.col -- LEFT
SELECT col(s) FROM table1 RIGHT JOIN table2 ON t1.col = t2.col -- RIGHT
SELECT col(s) FROM table1 FULL OUTER JOIN table2 ON t1.col=t2.col -- FULL
Operadores de conjuntos: UNION y UNION ALL
UNION combina dos o más conjuntos de resultados en una única tabla, pero solo si las consultas tienen el mismo número de columnas (y tipos compatibles). UNION elimina duplicados; UNION ALL los conserva (combina sin eliminar duplicados). Al ser una consulta, SELECT ... UNION ALL SELECT ... no modifica la base de datos.
Operadores, comodines y predicados
-
Operadores lógicos: AND (todas las condiciones), OR (al menos una) y NOT (niega). Se pueden combinar en una misma condición respetando la precedencia de operadores (el orden en que se evalúan las condiciones; NOT > AND > OR, alterable con paréntesis).
-
LIKE: usado con WHERE, busca por patrón mediante comodines
%(cualquier secuencia de caracteres) y_(un único carácter). Ejemplos:LIKE 'PAL%'→ empieza por PAL;LIKE '_a%'→ segundo carácter 'a';LIKE 'a__%'→ empieza por 'a' y tiene al menos 3 caracteres. A diferencia de=(comparación exacta), LIKE usa comodines. -
BETWEEN: selecciona valores dentro de un rango incluyendo los extremos inicial y final.
-
EXISTS: prueba la existencia de cualquier registro en una subconsulta.
INSERT y valores NULL
La sintaxis básica es INSERT INTO tabla VALUES (valor1, valor2, ...). Se pueden insertar valores nulos con la palabra clave NULL. Si el número de valores no coincide con el número de columnas, la sentencia falla y no se inserta nada.
Funciones y dialectos concretos
-
Oracle:
SELECT SYSTIMESTAMP FROM DUAL;devuelve la fecha del sistema con segundos fraccionados y la zona horaria del servidor donde reside la BD (tipoTIMESTAMP WITH TIME ZONE). -
SUBSTRING / MID:
SUBSTRING('SQL_Tutorial',5,3)devuelve 'Tut' (3 caracteres desde la posición 5). La función MID de MySQL extrae caracteres de un campo de texto. -
ROW_NUMBER(): función de ventana que asigna un número de fila secuencial a cada fila del resultado.
-
Transact-SQL: admite subconsultas también en la cláusula FROM; sus operadores de comparación válidos incluyen
=,<>,!=,<,>,<=,>=(=!no es válido).UNIONes un operador de conjuntos, no una función de agregación. -
SQL-92 amplió el estándar con múltiples novedades (nuevos tipos de datos, JOIN explícitos, subconsultas ampliadas, etc.).
Fuentes
-
PostgreSQL Global Development Group — Documentation 18: 7.2. Table Expressions (Joined Tables): https://www.postgresql.org/docs/current/queries-table-expressions.html
-
PostgreSQL — Documentation: SELECT / Aggregate Functions: https://www.postgresql.org/docs/current/functions-aggregate.html
-
Oracle — SQL Language Reference: SYSTIMESTAMP: https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/SYSTIMESTAMP.html
-
Oracle — Datetime Data Types and Time Zone Support: https://docs.oracle.com/en/database/oracle/oracle-database/21/nlspg/datetime-data-types-and-time-zone-support.html
-
ISO/IEC 9075 (SQL) — norma internacional del lenguaje SQL: https://www.iso.org/standard/76583.html
-
Microsoft Learn — Transact-SQL: Comparison Operators / Aggregate Functions: https://learn.microsoft.com/en-us/sql/t-sql/language-elements/comparison-operators-transact-sql