Hiparco

Recetas y trucos de GNU/Linux e informática en general

Alojado en http://guimi.net

SQL

Introducción a SQL (SQL-92)

Introducción

SQL (Structured Query Language / Lenguaje de Consulta Estructurado) es un lenguaje declarativo de acceso a bases de datos relacionales que implementa un DML (Data Manipulation Language / Lenguaje de Manipulación de Datos) y un DDL (Data Definition Language / Lenguaje de definición de datos).

Algunas de sus características son el manejo del álgebra y el cálculo relacional. En la actualidad SQL es el estándar de facto de la inmensa mayoría de los SGBD comerciales.

ANSI lo estandarizó en 1986 (SQL-86 o SQL1) y lo adoptó ISO al año siguiente. En 1992 se lanza un nuevo estándar ampliado y revisado del SQL llamado SQL-92 o SQL2. Ha habido modificaciones posteriores al estándar (la última es del 2006) que recogen los disparadores (triggers), el uso conjunto con XML, las columnas autonuméricas… Además cada implementación comercial incluye modificaciones particulares. Sin embargo el soporte al estándar SQL-92 es general y muy amplio.

DML (Data Manipulation Language / Lenguaje de Manipulación de Datos)

CONSULTAS BÁSICAS

SELECT [TOP X [PERCENT]] [DISTINCT | DISTINCTROW | ALL] columna AS renombrado
  FROM tablas
  [WHERE condiciones_sobre_registros]
  [ORDER BY columnaN [DESC | ASC]]

SELECT DISTINCT color AS colores
  FROM piezas
  WHERE (codigo > 10000)
    AND (color LIKE ‘A%’)
  ORDER BY color;

– Muestra como ‘colores’ los distintos colores
– de las piezas con código >10000 que empiezan por A, ordenados
– alfabéticamente.

CONSULTAS DE DATOS AGREGADOS

SELECT XXX(columna1) [, columna2...]
  FROM tablas
  [WHERE condiciones_sobre_registros]
  [GROUP BY columna2]
  [HAVING condiciones_sobre_agrupaciones]
  [ORDER BY columnaN [DESC | ASC]]

XXX: Count, Avg, Max, Min, Sum

SELECT tipo, Avg(precio) AS Precio_Medio
  FROM piezas
  WHERE precio <> 0
  GROUP BY tipo
  HAVING Precio_Medio > 10;

– Muestra para cada tipo el precio medio, tomando para calcular
– la media los registros con precio y mostrando solo aquellos
– tipos cuyo precio medio es > 10

| a | b |
+---+---+
| 2 | - |  Sum(a + b)      = 8
| 3 | 5 |  Sum(a) + Sum(b) = 10
+---+---+

CONDICIONES

expresion1 (< | >= | = | <= | < | <>) expresion2
espresion IS [NOT] NULL
expresion BETWEEN x AND y
expresion LIKE '%#_%' [ESCAPE '#']
expresion IN (x, y, z)
subconsulta

condicion1 (AND | OR) condicion2

TABLAS

tabla1 [INNER | LEFT | RIGHT] JOIN tabla2
  ON tabla1.columnaN = tabla2.columnaM

SELECT P.numero, P.fecha, C.nombre
  FROM pedidos P INNER JOIN clientes C
    ON P.cliente = C.codigo;

– Muestra numero y fecha de pedido y nombre del cliente
– que ha realizado el pedido
–
– es equivalente a

SELECT P.numero, P.fecha, C.nombre
  FROM pedidos P, clientes C
    ON P.cliente = C.codigo;

OPERADORES CONJUNTISTAS

consulta1 [UNION [DISTINCT] | EXCEPT | INTERSEC] consulta2
(consulta1 y consulta2 son compatibles)

SELECT pais
  FROM clientes
UNION
SELECT pais
  FROM proveedores;

-- Muestra una lista de paises de clientes y proveedores

SUBCONSULTAS

comparacion [ALL | ANY | SOME] consulta
expresion [NOT] IN consulta
[NOT] EXISTS consulta
[NOT] UNIQUE consulta

(ANY y SOME son equivalentes)

SELECT dni, nombre
  FROM empleados
  WHERE salario >=
    (SELECT Avg(salario)
       FROM empleados);

-- Muestra dni y nombre de los empleados que cobran
-- más que la media

SELECT dni, nombre
  FROM empleados
  WHERE salario > ALL
    (SELECT salario
       FROM empleados
       WHERE nivel=1);

-- Muestra dni y nombre de los empleados que cobran
-- más que todos los empleados de nivel 1 (individualmente)

SELECT dni, nombre
  FROM comerciales
  WHERE ciudad IN

    (SELECT DISTINCT ciudad
       FROM clientes);

-- Muestra dni y nombre de los comerciales que residen en
-- la misma ciudad que algún cliente

SELECT codigo, descripcion
  FROM piezas P
  WHERE NOT EXISTS

    (SELECT precio
       FROM ofertas O
       WHERE P.codigo = O.pieza)
    AND codigo > 100;

-- Muestra codigo y descripcion de las piezas con codigo > 100
-- para las que no existe ninguna oferta

SELECT codigo, descripcion
  FROM piezas P
  WHERE UNIQUE
    (SELECT precio
       FROM ofertas O
       WHERE P.codigo = O.pieza);

-- Muestra codigo y descripcion de las piezas
-- para las que existe una única oferta

MODIFICACIONES

INSERT INTO tabla [columnas]
  VALUES (valores)

INSERT INTO tabla [columnas]
  consulta

TRUNCATE TABLE tabla1 [, tabla2...]

DELETE FROM tabla
  [WHERE condiciones]
-- Si se va a hacer un borrado incondicional
-- es más óptimo usar TRUNCATE

UPDATE tabla1 [,tabla2...]
  SET columnaN = valorN
      [, columnaM = valorM ]
  WHERE condiciones_sobre_registros

UPDATE articulos A, nuevos_precios N
  SET A.precio = N.precio
  WHERE A.codigo = N.codigo

-- Actualiza la tabla de artículos con nuevos precios de otra tabla.

TRANSACCIONES

COMMIT
ROLLBACK

DDL (Data Definition Language / Lenguaje de definición de datos)

CREATE SCHEMA [IF NOT EXISTS] [catalogo.]esquema
  [AUTHORIZATION usuario]
  elementos

SET SCHEMA esquema

DROP SCHEMA [IF EXISTS] esquema

CREATE DOMAIN [IF NOT EXISTS] dominio [AS] tipo_dato
  [DEFAULT valor]
  [restricciones]

CREATE DOMAIN d_alta AS date
  DEFAULT current_time;
ALTER DOMAIN dominio
  { SET DEFAULT valor |
    DROP DEFAULT |
    ADD restriccion |
    DROP CONSTRAINT restriccion }

DROP DOMAIN [IF EXISTS] dominio [RESTRICT | CASCADE]

CREATE TABLE [IF NOT EXISTS] tabla
  columna1
    [DEFAULT valor]
    [restriccion_de_columna]
...
[restriccion_de_tabla]

CREATE TABLE tabla AS consulta

CREATE TABLE Copia AS (
  SELECT *
    FROM Tabla_a_Copiar
);

-- Se puede crear una tabla con el resultado de una consulta

[CONSTRAINT nombre_restriccion] -- No es obligatorio pero sí recomendable poner nombre
PRIMARY KEY (columnas) |
FOREIGN KEY (columnas) REFERENCES tabla_ref [columnas]
[ON UPDATE {NO ACTION | SET NULL | SET DEFAULT | CASCADE} ]
[ON DELETE {NO ACTION | SET NULL | SET DEFAULT | CASCADE} ]
UNIQUE (columnas) | -- Lo valores NULL NO se consideran valores iguales

CHECK (expresion)
[INITIALLY DEFERRED | INITIALLY IMMEDIATE]
[NOT DEFERRABLE | DEFERRABLE]

CREATE TABLE alumnos (
  codigo d_dni CONSTRAINT alumno_cp PRIMARY KEY
  nombre VARCHAR(100) NOT NULL,
  edad INTEGER
    CONSTRAINT CHECK (VALUE>0 AND VALUE <120),
  universidad VARCHAR(3) NOT NULL

    CONSTRAINT alumno_ca_univ REFERENCES universidad
      ON UPDATE CASCADE,
  sexo CHAR(1)

  CONSTRAINT sexo_ck CHECK (sexo IN ('O', 'A'))
);
ALTER TABLE tabla ADD [COLUMN] definicion_de_columna | definicion_de_restriccion
ALTER TABLE tabla DROP [COLUMN] definicion_de_columna | definicion_de_restriccion

ALTER TABLE tabla ALTER [COLUMN] columna SET expresion

DROP TABLE [IF EXISTS] tabla1 [, tabla2...]

CREATE ASSERTION restriccion
  CHECK condicion
  [INITIALLY DEFERRED | INITIALLY IMMEDIATE]
  [NOT DEFERRABLE | DEFERRABLE]

CREATE ASSERTION universidad_no_vacia
  CHECK ((SELECT Count(1) FROM universidad)>0);

CREATE VIEW vista [(columnas)]
  AS consulta

CREATE VIEW piezas_rojas
  AS SELECT *
       FROM piezas
       WHERE color = 'rojo';
DROP VIEW vista