El Lenguaje SQL

SQL (Structured Query Language) es el lenguaje estándar utilizado para gestionar y manipular bases de datos relacionales. Permite a los usuarios crear, modificar y consultar datos almacenados en una base de datos. Es fundamental para cualquier persona que trabaje con datos, desde desarrolladores y analistas hasta administradores de bases de datos.

SQL se compone de varios sublenguajes, cada uno con un propósito específico:

DDL (Data Definition Language): Lenguaje de Definición de Datos. Se utiliza para definir la estructura de la base de datos y sus objetos (tablas, vistas, índices, etc.).
DML (Data Manipulation Language): Lenguaje de Manipulación de Datos. Se utiliza para insertar, actualizar, eliminar y recuperar datos dentro de los objetos de la base de datos.
DCL (Data Control Language): Lenguaje de Control de Datos. Se utiliza para gestionar los permisos y el acceso a los datos.
TCL (Transaction Control Language): Lenguaje de Control de Transacciones. Se utiliza para gestionar las transacciones dentro de la base de datos.

DDL (Data Definition Language)

DDL se encarga de la estructura de la base de datos. Permite a los usuarios crear, modificar y eliminar objetos de la base de datos.

Comandos DDL principales:

  • CREATE: Se utiliza para crear nuevos objetos en la base de datos.
    • CREATE DATABASE: Crea una nueva base de datos.

      CREATE DATABASE MiEmpresaDB;
    • CREATE TABLE: Crea una nueva tabla en la base de datos. Debes especificar el nombre de la tabla, los nombres de las columnas y sus tipos de datos.

      CREATE TABLE Clientes (
      ID_Cliente INT PRIMARY KEY,
      Nombre VARCHAR(100) NOT NULL,
      Apellido VARCHAR(100) NOT NULL,
      Email VARCHAR(255) UNIQUE,
      FechaRegistro DATE
      );
      • PRIMARY KEY: Define una columna como clave primaria, lo que significa que sus valores deben ser únicos y no nulos, y se utiliza para identificar de forma única cada fila.
      • NOT NULL: Restringe que una columna no pueda contener valores nulos.
      • UNIQUE: Asegura que todos los valores en una columna sean diferentes.
      • FOREIGN KEY: Define una clave foránea, estableciendo una relación entre dos tablas (se verá en DML).
      • DEFAULT: Especifica un valor predeterminado para una columna si no se proporciona uno.
  • ALTER: Se utiliza para modificar la estructura de un objeto existente en la base de datos.
    • ALTER TABLE ADD COLUMN: Agrega una nueva columna a una tabla existente.

      ALTER TABLE Clientes ADD COLUMN Telefono VARCHAR(20);
    • ALTER TABLE DROP COLUMN: Elimina una columna de una tabla existente.

      ALTER TABLE Clientes DROP COLUMN Telefono;

    • ALTER TABLE MODIFY COLUMN (o ALTER COLUMN según el SGBD): Cambia el tipo de datos o las restricciones de una columna.

      -- SQL Server ALTER TABLE Clientes ALTER COLUMN Email VARCHAR(150);
      -- MySQL ALTER TABLE Clientes MODIFY COLUMN Email VARCHAR(150);

    • ALTER TABLE ADD CONSTRAINT: Agrega una restricción a una tabla existente (por ejemplo, una clave foránea).

      ALTER TABLE Pedidos ADD CONSTRAINT FK_ClienteID FOREIGN KEY (ID_Cliente) REFERENCES Clientes(ID_Cliente);

  • DROP: Se utiliza para eliminar objetos de la base de datos.
    • DROP TABLE: Elimina una tabla completa de la base de datos, incluyendo todos sus datos y su estructura.

      DROP TABLE Clientes;
    • DROP DATABASE: Elimina una base de datos completa.

      DROP DATABASE MiEmpresaDB;
  • TRUNCATE: Elimina todas las filas de una tabla, pero mantiene la estructura de la tabla. Es más rápido que DELETE para eliminar todas las filas, ya que no registra cada fila eliminada.

    TRUNCATE TABLE Ventas;

DML (Data Manipulation Language)

DML se encarga de la manipulación de los datos dentro de los objetos de la base de datos. Permite a los usuarios insertar, actualizar, eliminar y recuperar información.

Comandos DML principales:

  • INSERT INTO: Se utiliza para añadir nuevas filas (registros) a una tabla.

    INSERT INTO Clientes (ID_Cliente, Nombre, Apellido, Email, FechaRegistro) VALUES (1, 'Juan', 'Perez', 'juan.perez@example.com', '2023-01-15');

    -- Insertar múltiples filas INSERT INTO Clientes (ID_Cliente, Nombre, Apellido, Email, FechaRegistro) VALUES (2, 'Maria', 'Gomez', 'maria.gomez@example.com', '2023-02-20'),
    (3, 'Carlos', 'Lopez', 'carlos.lopez@example.com', '2023-03-01');
  • SELECT: Se utiliza para recuperar datos de una o más tablas. Es el comando más utilizado en SQL.
    • SELECT * FROM: Selecciona todas las columnas de una tabla.

      SELECT * FROM Clientes;
    • SELECT columna1, columna2 FROM: Selecciona columnas específicas.

      SELECT Nombre, Apellido, Email FROM Clientes;
    • WHERE: Filtra las filas basándose en una condición.

      SELECT Nombre, Apellido FROM Clientes WHERE FechaRegistro > '2023-02-01';
    • ORDER BY: Ordena el conjunto de resultados. ASC para ascendente (por defecto), DESC para descendente.

      SELECT Nombre, Apellido, FechaRegistro FROM Clientes ORDER BY FechaRegistro DESC;
    • GROUP BY: Agrupa filas que tienen los mismos valores en columnas especificadas en grupos. Se utiliza a menudo con funciones de agregación (COUNT, SUM, AVG, MIN, MAX).

      SELECT FechaRegistro, COUNT(ID_Cliente) AS TotalClientes FROM Clientes GROUP BY FechaRegistro;
    • HAVING: Filtra grupos creados por GROUP BY (similar a WHERE, pero para grupos).

      SELECT FechaRegistro, COUNT(ID_Cliente) AS TotalClientes FROM Clientes GROUP BY FechaRegistro HAVING COUNT(ID_Cliente) > 1;
    • LIMIT (MySQL, PostgreSQL) / TOP (SQL Server): Limita el número de filas devueltas.

      -- MySQL, PostgreSQL SELECT Nombre, Apellido FROM Clientes LIMIT 5;
      -- SQL Server SELECT TOP 5 Nombre, Apellido FROM Clientes;

  • UPDATE: Se utiliza para modificar datos existentes en una tabla.

    UPDATE Clientes SET Email = 'juan.nuevo@example.com' WHERE ID_Cliente = 1;

    -- Actualizar múltiples columnas UPDATE Clientes SET Email = 'maria.gomez.nuevo@example.com', Telefono = '555-1234' WHERE ID_Cliente = 2;

    ¡Advertencia! Siempre usa la cláusula WHERE con UPDATE para evitar actualizar todas las filas de la tabla.
  • DELETE FROM: Se utiliza para eliminar filas existentes de una tabla.

    DELETE FROM Clientes WHERE ID_Cliente = 3;

    ¡Advertencia! Siempre usa la cláusula WHERE con DELETE para evitar eliminar todas las filas de la tabla.

Ejemplo de query usando tres tablas con JOINs

Los JOINs son fundamentales en SQL para combinar filas de dos o más tablas basándose en una columna relacionada entre ellas.

Escenario: Queremos obtener una lista de todos los pedidos, incluyendo el nombre del cliente que realizó el pedido y el nombre del producto que se pidió, así como la cantidad y el precio unitario.

Asumiremos las siguientes tablas:

  1. Clientes:
    • ID_Cliente (PRIMARY KEY)
    • Nombre
    • Apellido
  2. Pedidos:
    • ID_Pedido (PRIMARY KEY)
    • ID_Cliente (FOREIGN KEY que referencia Clientes.ID_Cliente)
    • FechaPedido
  3. DetallePedidos:
    • ID_Detalle (PRIMARY KEY)
    • ID_Pedido (FOREIGN KEY que referencia Pedidos.ID_Pedido)
    • ID_Producto (FOREIGN KEY que referencia Productos.ID_Producto)
    • Cantidad
    • PrecioUnitario
  4. Productos:
    • ID_Producto (PRIMARY KEY)
    • NombreProducto
    • Categoria

Primero, vamos a crear estas tablas e insertar algunos datos de ejemplo (usando DDL y DML):

DDL: Creación de tablas

CREATE TABLE Clientes (
    ID_Cliente INT PRIMARY KEY,
    Nombre VARCHAR(100) NOT NULL,
    Apellido VARCHAR(100) NOT NULL
);

CREATE TABLE Productos (
    ID_Producto INT PRIMARY KEY,
    NombreProducto VARCHAR(255) NOT NULL,
    Categoria VARCHAR(100)
);

CREATE TABLE Pedidos (
    ID_Pedido INT PRIMARY KEY,
    ID_Cliente INT NOT NULL,
    FechaPedido DATE,
    FOREIGN KEY (ID_Cliente) REFERENCES Clientes(ID_Cliente)
);

CREATE TABLE DetallePedidos (
    ID_Detalle INT PRIMARY KEY,
    ID_Pedido INT NOT NULL,
    ID_Producto INT NOT NULL,
    Cantidad INT NOT NULL,
    PrecioUnitario DECIMAL(10, 2) NOT NULL,
    FOREIGN KEY (ID_Pedido) REFERENCES Pedidos(ID_Pedido),
    FOREIGN KEY (ID_Producto) REFERENCES Productos(ID_Producto)
);

DML: Inserción de datos

INSERT INTO Clientes (ID_Cliente, Nombre, Apellido) VALUES
(1, 'Ana', 'García'),
(2, 'Luis', 'Martínez'),
(3, 'Sofía', 'Rodríguez');

INSERT INTO Productos (ID_Producto, NombreProducto, Categoria) VALUES
(101, 'Laptop Pro', 'Electrónica'),
(102, 'Teclado Mecánico', 'Periféricos'),
(103, 'Mouse Óptico', 'Periféricos'),
(104, 'Monitor UltraWide', 'Electrónica');

INSERT INTO Pedidos (ID_Pedido, ID_Cliente, FechaPedido) VALUES
(1, 1, '2024-01-20'),
(2, 2, '2024-01-22'),
(3, 1, '2024-01-25'),
(4, 3, '2024-02-01');

INSERT INTO DetallePedidos (ID_Detalle, ID_Pedido, ID_Producto, Cantidad, PrecioUnitario) VALUES
(1001, 1, 101, 1, 1200.00),
(1002, 1, 102, 1, 80.00),
(1003, 2, 103, 2, 25.00),
(1004, 3, 101, 1, 1150.00),
(1005, 3, 104, 1, 300.00),
(1006, 4, 102, 1, 85.00);

Ahora, el query entre las tres tablas con JOINs:

Utilizaremos INNER JOIN para combinar las tablas. Un INNER JOIN solo devuelve las filas cuando hay una coincidencia en ambas tablas.

SELECT
    C.Nombre AS NombreCliente,
    C.Apellido AS ApellidoCliente,
    P.ID_Pedido,
    P.FechaPedido,
    Pr.NombreProducto,
    DP.Cantidad,
    DP.PrecioUnitario,
    (DP.Cantidad * DP.PrecioUnitario) AS Subtotal
FROM
    Pedidos AS P                      -- Alias P para la tabla Pedidos
INNER JOIN
    Clientes AS C ON P.ID_Cliente = C.ID_Cliente  -- Unir Pedidos con Clientes
INNER JOIN
    DetallePedidos AS DP ON P.ID_Pedido = DP.ID_Pedido -- Unir Pedidos con DetallePedidos
INNER JOIN
    Productos AS Pr ON DP.ID_Producto = Pr.ID_Producto; -- Unir DetallePedidos con Productos

Explicación del Query:

  • SELECT ... FROM Pedidos AS P: Iniciamos seleccionando columnas y le damos un alias P a la tabla Pedidos para simplificar la escritura.
  • INNER JOIN Clientes AS C ON P.ID_Cliente = C.ID_Cliente:
    • Combina la tabla Pedidos (P) con la tabla Clientes (C).
    • La cláusula ON especifica la condición de unión: las filas se combinan cuando el ID_Cliente en Pedidos coincide con el ID_Cliente en Clientes. Esto vincula cada pedido con el cliente que lo realizó.
  • INNER JOIN DetallePedidos AS DP ON P.ID_Pedido = DP.ID_Pedido:
    • Combina el resultado de la unión anterior con la tabla DetallePedidos (DP).
    • La condición es que el ID_Pedido en Pedidos coincida con el ID_Pedido en DetallePedidos. Esto vincula cada pedido con sus detalles de productos.
  • INNER JOIN Productos AS Pr ON DP.ID_Producto = Pr.ID_Producto:
    • Finalmente, combina el resultado con la tabla Productos (Pr).
    • La condición es que el ID_Producto en DetallePedidos coincida con el ID_Producto en Productos. Esto nos permite obtener el nombre del producto para cada línea de detalle del pedido.
  • AS: Se utiliza para crear alias de tablas o columnas, haciendo el query más legible.
  • (DP.Cantidad * DP.PrecioUnitario) AS Subtotal: Es una columna calculada que muestra el subtotal de cada línea de pedido.

Resultado de la consulta:

NombreCliente ApellidoCliente ID_Pedido FechaPedido NombreProducto Cantidad PrecioUnitario Subtotal
Ana García 1 2024-01-20 Laptop Pro 1 1200.00 1200.00
Ana García 1 2024-01-20 Teclado Mecánico 1 80.00 80.00
Luis Martínez 2 2024-01-22 Mouse Óptico 2 25.00 50.00
Ana García 3 2024-01-25 Laptop Pro 1 1150.00 1150.00
Ana García 3 2024-01-25 Monitor UltraWide 1 300.00 300.00
Sofía Rodríguez 4 2024-02-01 Teclado Mecánico 1 85.00 85.00