Guía de SQL

SQL sirve para consultar y modificar datos. Esta guía usa T-SQL, el dialecto de SQL Server. Las consultas de lectura de los primeros capítulos se pueden probar en La última función. Los ejemplos de escritura están pensados para una base de prácticas con permisos de escritura.

Tablas, filas y tipos

Una tabla agrupa datos de un mismo tipo de entidad. En acceso, cada fila es un paso por una sala. Cada columna describe un aspecto del acceso. id es la clave primaria y distingue cada fila. codigo referencia la clave del pase en otra tabla.

Tipo Para qué sirve Ejemplo
int Enteros 9
decimal(8,2) Cantidades exactas con decimales 19.95
nvarchar(80) Texto Unicode de hasta 80 unidades UTF-16 N'Inés Vidal'
date Fecha '2026-03-22'
datetime2 Fecha y hora '2026-03-22T21:40:00'
bit Indicador lógico 0 o 1

NULL indica ausencia de valor. Para buscarlo usa IS NULL o IS NOT NULL. Una comparación con = NULL produce un resultado desconocido.

Elegir datos con SELECT y FROM

SELECT indica qué columnas devuelve la consulta. FROM indica de qué tabla proceden. Separa las columnas con comas. AS pone un nombre a una columna del resultado. El punto y coma cierra la sentencia.

SELECT objeto, ubicacion AS sala
FROM inventario;

SELECT * devuelve todas las columnas. Para leer una tabla desconocida puede ser útil. Al preparar un informe, elige solo las columnas que necesitas. DISTINCT elimina filas repetidas del resultado considerando todas las columnas elegidas.

Filtrar con WHERE, AND, OR y LIKE

WHERE conserva las filas cuya condición es verdadera. El texto se escribe entre comillas simples. En SQL Server, el prefijo N conserva caracteres Unicode. Si el texto contiene una comilla, escríbela dos veces. Los números se escriben sin comillas.

SELECT codigo, sala, minutos_antes
FROM acceso
WHERE sala = N'Archivo' AND minutos_antes <= 10;

AND exige que se cumplan las dos condiciones. OR permite cualquiera de ellas. SQL evalúa AND antes que OR, así que usa paréntesis para mostrar qué alternativas van juntas.

SELECT codigo, sala, minutos_antes
FROM acceso
WHERE (sala = N'Archivo' OR sala = N'Escenario')
  AND minutos_antes <= 10;

LIKE busca un patrón en texto. % representa cero o más caracteres y _ representa uno. N'A%' encuentra valores que empiezan por A y N'%Archivo%' encuentra los que contienen Archivo. La distinción entre mayúsculas y acentos depende de la intercalación de la columna.

SELECT codigo, sala, minutos_antes
FROM acceso
WHERE sala LIKE N'Arch%' AND minutos_antes BETWEEN 3 AND 10;

Otros operadores habituales son <, >, >=, <>, IN (...) y NOT. BETWEEN incluye ambos extremos. Para días completos sobre una columna con hora, suele ser más claro usar un inicio incluido y un final excluido.

Ordenar y limitar con ORDER BY y TOP

ORDER BY ordena el resultado. ASC va de menor a mayor y DESC de mayor a menor. Si dos filas empatan, puedes añadir otra columna para resolver el empate. TOP (1) devuelve la primera fila del orden indicado.

SELECT TOP (1) codigo, minutos_antes
FROM acceso
WHERE sala = N'Archivo'
ORDER BY minutos_antes ASC, id ASC;

Sin ORDER BY, SQL Server no garantiza el orden. Usa OFFSET ... FETCH junto a ORDER BY para paginar.

Contar y resumir con GROUP BY y HAVING

GROUP BY reúne filas con el mismo valor. COUNT(*) cuenta filas y COUNT(columna) cuenta valores presentes. SUM, AVG, MIN y MAX calculan totales, medias y extremos.

SELECT codigo, COUNT(*) AS entradas
FROM acceso
WHERE sala = N'Archivo'
GROUP BY codigo
HAVING COUNT(*) >= 2;

WHERE filtra filas antes de agrupar. HAVING filtra los grupos después. Una columna que aparezca en SELECT debe formar parte de GROUP BY o de una agregación.

Relacionar tablas con JOIN

INNER JOIN combina las filas que coinciden según ON. Puedes abreviar el nombre de cada tabla con un alias y usarlo para indicar de qué tabla viene cada columna.

SELECT a.sala, p.persona
FROM acceso AS a
INNER JOIN pase AS p ON a.codigo = p.codigo;

LEFT JOIN conserva también las filas de la izquierda sin coincidencia. Las columnas de la derecha quedan en NULL. RIGHT JOIN invierte ese papel, FULL JOIN conserva las filas sin pareja de ambos lados y CROSS JOIN combina cada fila con todas las del otro lado. Una relación de uno a varios genera una fila por cada coincidencia. Si aparecen más filas de las que esperabas, revisa las claves antes de añadir DISTINCT.

Subconsultas, CTE y conjuntos

Una subconsulta obtiene datos que necesita otra consulta. EXISTS comprueba si encuentra al menos una fila. IN compara con una lista de valores. Una subconsulta usada como valor debe devolver como máximo una fila.

SELECT p.persona
FROM pase AS p
WHERE EXISTS (
    SELECT 1 FROM acceso AS a
    WHERE a.codigo = p.codigo AND a.sala = N'Archivo'
);

Una CTE da nombre a un resultado intermedio para la sentencia que le sigue. Empieza con WITH. Si hay una sentencia anterior en el lote, ciérrala con punto y coma.

WITH Entradas AS (
    SELECT codigo, COUNT(*) AS total
    FROM acceso
    GROUP BY codigo
)
SELECT codigo, total FROM Entradas WHERE total > 1;

UNION ALL concatena resultados con el mismo número de columnas y tipos compatibles. UNION elimina duplicados. INTERSECT devuelve filas comunes y EXCEPT devuelve las que solo están en el primer resultado.

Funciones de ventana y expresiones

Una función de ventana calcula un valor sobre filas relacionadas y conserva el detalle de cada fila. PARTITION BY define el grupo y ORDER BY dentro de OVER define el orden del cálculo.

SELECT codigo, sala, minutos_antes,
       ROW_NUMBER() OVER (PARTITION BY codigo ORDER BY minutos_antes, id) AS orden
FROM acceso;

RANK asigna la misma posición a los empates. LAG permite leer un valor de la fila anterior. CASE elige un valor según condiciones. COALESCE devuelve el primer valor distinto de NULL. CAST convierte tipos cuando los datos lo permiten.

Crear y modificar estructuras

CREATE TABLE crea una tabla. ALTER TABLE cambia su estructura y DROP TABLE la elimina. Las restricciones protegen los datos. PRIMARY KEY identifica filas, FOREIGN KEY exige una referencia válida, CHECK comprueba condiciones y NOT NULL exige un valor.

CREATE TABLE dbo.practica_pase (
    codigo nvarchar(10) NOT NULL PRIMARY KEY,
    persona nvarchar(80) NOT NULL,
    usos int NOT NULL CHECK (usos >= 0)
);

Una vista guarda la definición de una consulta. Un índice puede acelerar filtros y cruces a cambio de espacio y trabajo adicional al modificar filas.

Insertar, actualizar y borrar datos

INSERT añade filas. Especifica las columnas para que cada valor quede asociado de forma clara. UPDATE cambia columnas de las filas que cumplen el filtro y DELETE elimina esas filas.

INSERT INTO dbo.practica_pase (codigo, persona, usos)
VALUES (N'A-07', N'Inés Vidal', 0);

UPDATE dbo.practica_pase
SET usos = usos + 1
WHERE codigo = N'A-07';

DELETE FROM dbo.practica_pase
WHERE codigo = N'A-07';

Antes de ejecutar un UPDATE o DELETE, ejecuta un SELECT con el mismo filtro y revisa las filas afectadas. Si omites WHERE, la operación alcanza toda la tabla. TRUNCATE TABLE vacía toda la tabla y tampoco admite filtros.

Transacciones, procedimientos y permisos

Una transacción agrupa cambios. BEGIN TRANSACTION la abre, COMMIT confirma y ROLLBACK revierte. En una práctica puedes observar el cambio antes de decidir si lo guardas.

BEGIN TRANSACTION;
UPDATE dbo.practica_pase SET usos = 2 WHERE codigo = N'A-07';
SELECT * FROM dbo.practica_pase WHERE codigo = N'A-07';
ROLLBACK TRANSACTION;

CREATE PROCEDURE guarda un conjunto de instrucciones que puede recibir parámetros. EXEC lo ejecuta. En SQL Arcade los niveles indican qué procedimientos están disponibles.

GRANT concede un permiso, REVOKE retira una concesión o denegación explícita y DENY deniega. La consola de juego usa cuentas limitadas a los datos de cada caso. Puedes usar las consultas de lectura para investigar y estudiar los ejemplos de escritura en una base de prácticas.