You are on page 1of 89

Bases de Datos

Lenguaje SQL
Profesor: Gilberto Gutiérrez R.

Departamento de Ciencias de la Computación y Tecnologı́as de la Información


Facultad de Ciencias Empresariales
Universidad del Bı́o-Bı́o
Contenido

1. Introducción
2. Definición de datos
3. Consultas básicas en SQL
4. Consultas más complejas
5. Sentencias de inserción, eliminación y de actualización en SQL
6. Vistas (tablas virtuales) en SQL
7. Utilización de índices
8. Procedimientos almacenados
9. Triggers de Bases de datos
Definición de datos

Creando la tabla EMPLEADOS


CREATE TABLE EMPLEADO (
NOMBRE VARCHAR(15) NOT NULL,
INIC CHAR,
APELLIDO VARCHAR(15) NOT NULL,
NSS CHAR(9) NOT NULL,
FECHA_NCTO DATE,
DIRECCION VARCHAR(15),
SEXO CHAR,
SALARIO DECIMAL(10,2),
NSS_SUPERV CHAR(9),
ND INT NOT NULL,
PRIMARY KEY(NSS),
FOREIGN KEY(NSS-SUPERV) REFERENCES EMPLEADO (NSS),

FOREIGN KEY(ND) REFERENCES DEPARTAMENTO (NUMEROD));


Definición de datos (cont.)

creando la tabla TRABAJA_EN


CREATE TABLE TRABAJA_EN (
NSSE CHAR(9) NOT NULL,
NP INT NOT NULL,
HORAS DECIMAL(3,1) NOT NULL,
PRIMARY KEY(NSSE, NP),
FOREIGN KEY (NSSE) REFERENCES EMPLEADO(NSS),
FOREIGN KEY (NP) REFERENCES PROYECTO(NUMEROP));
Definición de datos (cont.)

Eliminación de tablas
DROP TABLE EMPLEADO;
Modificación del esquema de la tabla
ALTER TABLE EMPLEADO ADD PUESTO VARCHAR(10);
Consultas básicas en SQL

SELECT <lista de atributos>


FROM <lista de tablas>
WHERE <condición>
donde:
<lista de atributos> es una lista de atributos cuyos valores van a
ser recuperados
<lista de tablas> es una lista de nombres de las relaciones
necesarias para procesar las consultas
<condición> es una expresión booleana que identifica las tuplas
que van a ser recuperadas por la consulta
Consultas básicas en SQL (cont.)

Ejemplos:
Recuperar la fecha nacimiento y dirección del empleado cuyo nombre
es ’John B. Samith’.
SELECT FECHA_NCTO, DIRECCION
FROM EMPLEADO
WHERE NOMBRE=’John’ and INIC=’B’ and APELLIDO=’Smith’;

Resultado:
fecha_ncto | direccion
------------+--------------------------
1965-01-09 | 731 Fondren, Houston, TX
(1 row)

En álgebra relacional sería:


πFECHA_NAC, DIRECCION
(σN OM BRE=′ John′ and IN IC=′ B ′ and AP ELLIDO=′ Smith′ (EMPLEADO))
Consultas básicas en SQL (cont.)

Listar los nombres y salario de los empleados cuyo sueldo supera los
30.000 dólares
SELECT NOMBRE, SALARIO
FROM EMPLEADO
WHERE SALARIO > 30000;

Resultado:

nombre | salario
----------+----------
Franklin | 40000.00
Jennifer | 43000.00
Ramesh | 38000.00
James | 55000.00
(4 rows)
Consultas básicas en SQL (cont.)

Recuperar los nombres y dirección de los empleados que trabajan en


el departamento de ’Investigación’
SELECT NOMBRE, DIRECCION
FROM EMPLEADO, DEPARTAMENTO
WHERE NOMBRED=’Investigacion’ AND NUMEROD=ND;

Resultado:
nombre | apellido | direccion
----------+----------+--------------------------
John | Smith | 731 Fondren, Houston, TX
Franklin | Worg | 638 Voss, Houston, TX
Ramesh | Narayan | 975 Fire Oak, Humble, TX
Joyce | English | 5631 Rice, Houston, TX
(4 rows)
Consultas simples

De cada proyecto ubicado en ’Stafford’, obtener una lista con el número de proyecto, el
número del departamento controlador y el apellido, dirección y fecha de nacimiento del jefe
del departamento.
SELECT NUMEROP, NUMD, APELLIDO, DIRECCION, FECHA_NCTO
FROM PROYECTO, DEPARTAMENTO, EMPLEADO
WHERE NUMD = NUMEROD AND NSS_JEFE = NSS AND LOCALIZACIONP=’Stafford’;

numerop | numd | apellido | direccion | fecha_ncto


---------+------+----------+-------------------------+------------
30 | 4 | Wallace | 291 Berry, Bellaire, TX | 1941-06-20
10 | 4 | Wallace | 291 Berry, Bellaire, TX | 1941-06-20
(2 rows)
Atributos ambiguos y asignación de alias

Recuperar los nombres y dirección de los empleados que trabajan en el departamento de


’Investigación’
SELECT EMPLEADO.NOMBRE, APELLIDO, DIRECCION
FROM EMPLEADO, DEPARTAMENTO
WHERE DEPARTAMENTO.NOMBRED= ’Investigacion’ AND
DEPARTAMENTO.NUMEROD= EMPLEADO.ND;

nombre | apellido | direccion


----------+----------+--------------------------
John | Smith | 731 Fondren, Houston, TX
Franklin | Worg | 638 Voss, Houston, TX
Ramesh | Narayan | 975 Fire Oak, Humble, TX
Joyce | English | 5631 Rice, Houston, TX
(4 rows)
Atributos ambiguos y asignación de alias

De cada empleado recuperar su nombre de pila y apellido y los de sus supervisor inmediato

SELECT E.NOMBRE, E.APELLIDO, S.NOMBRE, S.APELLIDO


FROM EMPLEADO AS E, EMPLEADO AS S
WHERE E.NSS_SUPERV = S.NSS;

nombre | apellido | nombre | apellido


----------+----------+----------+----------
John | Smith | Franklin | Worg
Franklin | Worg | James | Borg
Alicia | Zelaya | Jennifer | Wallace
Jennifer | Wallace | James | Borg
Ramesh | Narayan | Franklin | Worg
Joyce | English | Franklin | Worg
Ahmad | Jabbar | Jennifer | Wallace
(7 rows)

También puede ser


FROM EMPLEADO E, EMPLEADO S
Renombrar los atributos de la relación

EMPLEADO AS E(NP, IN,AP, NSS, FN, DIR, SEX, SAL, NSSS, NF)
También puede ser así
SELECT NOMBRE AS NOMBRE_PILA
FROM EMPLEADO;
nombre_pila
-------------
John
Franklin
Alicia
Jennifer
Ramesh
Joyce
Ahmad
James
(8 rows)
Cláusula WHERE no especificadas y uso de *

SELECT NSS
FROM EMPLEADO;
nss
-----------
123456789
333445555
999887777
987654321
666884444
453453453
987987987
888665555
(8 rows)
Cláusula WHERE no especificadas y uso de *

SELECT NSS, NOMBRED


FROM EMPLEADO, DEPARTAMENTO
nss | nombred
-----------+----------------
123456789 | Investigacion
333445555 | Investigacion
999887777 | Investigacion
987654321 | Investigacion
666884444 | Investigacion
453453453 | Investigacion
987987987 | Investigacion
888665555 | Investigacion
123456789 | Administracion
333445555 | Administracion
999887777 | Administracion
987654321 | Administracion
... ....
Cláusula WHERE no especificadas y uso de *

SELECT *
FROM EMPLEADO
WHERE ND=5

SELECT *
FROM EMPLEADO, DEPARTAMENTO
WHERE NOMBRED=’Investigacion’ AND ND = NUMEROD;

SELECT *
FROM EMPLEADO, DEPARTAMENTO;
Tablas como conjuntos

SQL suele tratar una tabla no como un conjunto sino como un


multiconjunto
Pueden aparecer tuplas repetidas en una tabla y en el resultado de
una consulta
Algunas razones para mantener las tuplas repetidas:

La eliminación de tuplas es una operación muy costosa


El usuario quiere ver las tuplas rpetidas
Funciones de agregación (veremos esto más adelante)
Tablas como conjuntos (continuación)

DISTINCT– Eliminación de tuplas repetidas


ALL – Se conservan las tuplas repetidas
Ejemplos:
SELECT ALL SALARIO
FROM EMPLEADO
salario
----------
30000.00
40000.00
25000.00
43000.00
38000.00
25000.00
25000.00
55000.00
(8 rows)
Tablas como conjuntos (continuación)

Ejemplos:
SALARIO
SELECT DISTINCT
FROM EMPLEADO
salario
----------
25000.00
30000.00
38000.00
40000.00
43000.00
55000.00
(6 rows)
Tablas como conjuntos (continuación)

Union (UNION), Intersección (INTERSECT) y diferencia de conjuntos


(EXCEPT)
Ejemplo:
Prepare una lista con todos los números de proyectos en los que participa un empleado de
apellido ’Smith’, sea como trabajador o como jefe del departamento que controla el proyecto
(SELECT DISTINCT NUMEROP
FROM PROYECTO, DEPARTAMENTO, EMPLEADO
WHERE NUMD = NUMEROD AND NSS_JEFE = NSS AND
APELLIDO = ’Smith’ )
UNION
(SELECT DISTINCT NP
FROM TRABAJA_EN, EMPLEADO
WHERE NSSE= NSS AND APELLIDO=’Smith’);
numerop
---------
1
2
(2 rows)
Subcadenas y operadores aritméticos

LIKE, % y -
Recuperar todos los empleados cuya dirección es Houston, Texas
SELECT NOMBRE,APELLIDO
FROM EMPLEADO
WHERE DIRECCION LIKE ’%Houston, TX%’ ;

nombre | apellido
----------+----------
John | Smith
Franklin | Worg
Joyce | English
Ahmad | Jabbar
James | Borg
(5 rows)
Los salarios resultantes de los empleados si estos se aumentan en un
10%
Ejemplo:

SELECT NOMBRE, APELLIDO, 1.1*SALARIO AS NvoSalario


FROM EMPLEADO ;
nombre | apellido | nvosalario
----------+----------+------------
John | Smith | 33000.000
Franklin | Worg | 44000.000
Alicia | Zelaya | 27500.000
Jennifer | Wallace | 47300.000
Ramesh | Narayan | 41800.000
Joyce | English | 27500.000
Ahmad | Jabbar | 27500.000
James | Borg | 60500.000
(8 rows)
Operador between

SELECT NOMBRE, SALARIO


FROM EMPLEADO
WHERE (SALARIO BETWEEN 30000 AND 40000);

nombre | salario
----------+----------
John | 30000.00
Franklin | 40000.00
Ramesh | 38000.00
(3 rows)
Ordenación

Obtener una lista de los empleados y de los proyectos en los que


trabajan, ordenados por departamento, y, dentro de departamento,
alfabéticamente por apellido y nombre
SELECT NOMBRED, APELLIDO, E.NOMBRE, PROYECTO.NOMBRE
FROM DEPARTAMENTO, EMPLEADO E, TRABAJA_EN, PROYECTO
WHERE NUMEROD=ND AND NSS=NSSE AND NP= NUMEROP
ORDER BY NOMBRED, APELLIDO, E.NOMBRE;
nombred | apellido | nombre | nombre
----------------+----------+----------+----------------
Administracion | Jabbar | Ahmad | Automatizacion
Administracion | Jabbar | Ahmad | Nuevos Benefic
Administracion | Wallace | Jennifer | Reorganizacion
Administracion | Wallace | Jennifer | Nuevos Benefic
Administracion | Zelaya | Alicia | Automatizacion
Administracion | Zelaya | Alicia | Nuevos Benefic
Direccion | Borg | James | Reorganizacion
Investigacion | English | Joyce | ProductoY
...
Consultas SQL más complejas
Consultas anidadas / subconsultas

Caso: obtener valores existentes en la base de datos para luego utilizarlos en una condición.
Estos son bloques completos SELECT... FROM ... WHERE dentro de la claúsula WHERE
de otra consulta.
Ejemplo: Prepare una lista con todos los números de proyectos en los que participa un
empleado de apellido ’Smith’, sea como trabajador o como jefe del departamento que
controla el proyecto
SELECT DISTINCT NUMEROP
FROM PROYECTO
WHERE NUMEROP IN (SELECT NUMEROP
FROM PROYECTO, DEPARTAMENTO, EMPLEADO
WHERE NUMD=NUMEROD AND NSS_JEFE=NSS AND APELLIDO =’Smith’)
OR
NUMEROP IN (SELECT NP
FROM TRABAJA_EN, EMPLEADO
WHERE NSSE=NSS AND APELLIDO=’Smith’);
numerop
---------
1
2
(2 rows)
Consultas anidadas / subconsultas

SELECT DISTINCT NSSE


FROM TRABAJA_EN
WHERE (NP,HORAS) IN (SELECT NP, HORAS FROM TRABAJA_EN
WHERE NSSE= ’123456789’);

nsse
-----------
123456789
(1 row)
Consultas anidadas / subconsultas

Operadores:

INCompara el valor v con un conjunto o multiconjunto de valores


V y evalúa a TRUE si v es uno de los elementos de V
ANY ⇐⇒ SOME, ALL (>, >=, <, <=, =, <>)

=ANY o =SOME es equivalente a IN

Ejemplo: Los nombres de los empleados que cuyo salario es mayor que el de todos los
empleados del departamento 5
SELECT APELLIDO, NOMBRE
FROM EMPLEADO
WHERE SALARIO > ALL (SELECT SALARIO FROM EMPLEADO WHERE ND =5);

apellido | nombre
----------+----------
Wallace | Jennifer
Borg | James
(2 rows)
Consultas anidadas / subconsultas

Ambiguedades de los nombres de los atributos


Ejemplo:
El nombre y apellido de cada empleado que tenga un familiar con el mismo nombre de pila y
sexo que el e mpleado
SELECT E.NOMBRE, E.APELLIDO
FROM EMPLEADO AS E
WHERE E.NSS IN (SELECT NSSE
FROM DEPENDIENTE
WHERE E.NOMBRE = NOMBRE_DEPENDIENTE
AND E.SEXO = SEXO);

--------+----------
(0 rows)

La regla es: la referencia a un atributo no calificado se refiere a la


relación declarada en la consulta anidada más interior
Consultas anidadas correlacionadas

Siempre que una claúsula WHERE de una consulta anidada hace


referencia a un atributo de una relación declarada en una consulta
externa.
La consulta anida se evalua una vez por cada tupla (o combinación de
tuplas) en la consulta externa.
En la consulta anterior: Por cada tupla empleado, se evalua la consulta
anidada
En general una consulta anidada y que emplee los operadores = o IN siempre puede
expresarse como una consulta de un sólo bloque Ejemplo:
SELECT E.NOMBRE, E.APELLIDO
FROM EMPLEADO AS E, DEPENDIENTE AS D
WHERE E.NSS = D.NSSE AND E.SEXO = D.SEXO AND
E.NOMBRE = D.NOMBRE_DEPENDIENTE
Función EXISTS (NOT EXISTS)

Sirve para comprobar si el resultado de una consulta anidada


correlacionada es o no vacío. Ejemplo:
El nombre y apellido de cada empleado que tenga un familiar con el mismo nombre de pila y
sexo que el e mpleado
SELECT E.NOMBRE, E.APELLIDO
FROM EMPLEADO AS E
WHERE EXISTS (SELECT *
FROM DEPENDIENTE
WHERE E.NSS = NSSE AND
E.NOMBRE = NOMBRE_DEPENDIENTE
AND E.SEXO = SEXO);

--------+----------
(0 rows)
Función EXISTS (NOT EXISTS)

Recupere los nombres de empleados que no tienen familiares dependientes


SELECT NOMBRE, APELLIDO
FROM EMPLEADO AS E
WHERE NOT EXISTS (SELECT *
FROM DEPENDIENTE
WHERE E.NSS = NSSE);

nombre | apellido
--------+----------
Alicia | Zelaya
Ramesh | Narayan
Joyce | English
Ahmad | Jabbar
James | Borg
(5 rows)
Función EXISTS (NOT EXISTS)

Recupere los nombres y apellidos de los jefes de departamento y que tienen por lo menos
un familiar dependiente
SELECT NOMBRE, APELLIDO
FROM EMPLEADO AS E
WHERE EXISTS (SELECT *
FROM DEPENDIENTE
WHERE E.NSS = NSSE)
AND
EXISTS (SELECT *
FROM DEPARTAMENTO
WHERE NSS= NSS_JEFE);

nombre | apellido
----------+----------
Franklin | Worg
Jennifer | Wallace
(2 rows)
Función EXISTS (NOT EXISTS)

Recupere los nombres y apellidos de todos los empleados que trabajan en todos los
proyectos controlados por el departamento número 5
SELECT NOMBRE, APELLIDO
FROM EMPLEADO
WHERE NOT EXISTS
( ( SELECT NUMEROP
FROM PROYECTO
WHERE NUMD = 5)
EXCEPT
( SELECT NP
FROM TRABAJA_EN
WHERE NSS= NSSE));

nombre | apellido
--------+----------
(0 rows)
Conjuntos explícitos

Recupere el NSS de todos los empleados que trabajan en los proyectos 1, 2 ó 3


SELECT DISTINCT NSSE
FROM TRABAJA_EN
WHERE NP IN (1,2,3);
nsse
-----------
123456789
333445555
453453453
666884444
(4 rows)
Valores null (IS NULL, IS NOT NULL)

Recupere los nombres de los empleados que no tienen supervisores


SELECT NOMBRE, APELLIDO
FROM EMPLEADO
WHERE NSS_SUPERV IS NULL;

nombre | apellido
--------+----------
James | Borg
(1 row)
Renombrar atributos y relaciones

De cada empleado recuperar su apellido y el apellido de su supervisor inmediato


SELECT E.APELLIDO AS NOMBRE_EMPLEADO,
S.APELLIDO AS NOMBRE_SUPERVISOR
FROM EMPLEADO AS E, EMPLEADO AS S
WHERE E.NSS_SUPERV=S.NSS;

nombre_empleado | nombre_supervisor
-----------------+-------------------
Smith | Worg
Worg | Borg
Zelaya | Wallace
Wallace | Borg
Narayan | Worg
English | Worg
Jabbar | Wallace
Tablas combinadas (Join)

Recuperar los nombres y dirección de los empleados que trabajan en el departamento de


Investigación
SELECT EMPLEADO.NOMBRE, APELLIDO, DIRECCION
FROM (EMPLEADO JOIN DEPARTAMENTO ON ND = NUMEROD)
WHERE DEPARTAMENTO.NOMBRED= ’Investigacion’;

nombre | apellido | direccion


----------+----------+--------------------------
John | Smith | 731 Fondren, Houston, TX
Franklin | Worg | 638 Voss, Houston, TX
Ramesh | Narayan | 975 Fire Oak, Humble, TX
Joyce | English | 5631 Rice, Houston, TX
(4 rows)
Tablas combinadas (Natural Join)

Recuperar los nombres y dirección de los empleados que trabajan en el departamento de


Investigación
SELECT EMPLEADO.NOMBRE, APELLIDO, DIRECCION
FROM (EMPLEADO NATURAL JOIN
DEPARTAMENTO AS DEPTO(NOMBRED, ND, NSSG, FECHAIG))
WHERE NOMBRED= ’Investigacion’;

nombre | apellido | direccion


----------+----------+--------------------------
John | Smith | 731 Fondren, Houston, TX
Franklin | Worg | 638 Voss, Houston, TX
Ramesh | Narayan | 975 Fire Oak, Humble, TX
Joyce | English | 5631 Rice, Houston, TX
(4 rows)
Tablas combinadas (OUTER JOIN)

De cada empleado recuperar su apellido y el apellido de su supervisor inmediato


SELECT E.APELLIDO AS NOMBRE_EMPLEADO,
S.APELLIDO AS NOMBRE_SUPERVISOR
FROM (EMPLEADO AS E LEFT OUTER JOIN EMPLEADO AS S
ON E.NSS_SUPERV= S.NSS);

nombre_empleado | nombre_supervisor
-----------------+-------------------
Smith | Worg
Worg | Borg
Zelaya | Wallace
Wallace | Borg
Narayan | Worg
English | Worg
Jabbar | Wallace
Borg |
(8 rows)

LEFT OUTER JOIN, RIGHT OUTER JOIN, FULL OUTER JOIN


Tablas combinadas (varias reuniones)

De cada proyecto ubicado en ’Stafford’, obtener una lista con el número de proyecto, el
número del departamento controlador y el apellido, dirección y fecha de nacimiento del jefe
del departamento.
SELECT NUMEROP, NUMD, APELLIDO, DIRECCION, FECHA_NCTO
FROM ((PROYECTO JOIN DEPARTAMENTO ON NUMD = NUMEROD)
JOIN EMPLEADO ON NSS_JEFE = NSS)
WHERE LOCALIZACIONP = ’Stafford’;

numerop | numd | apellido | direccion | fecha_ncto


---------+------+----------+-------------------------+------------
30 | 4 | Wallace | 291 Berry, Bellaire, TX | 1941-06-20
10 | 4 | Wallace | 291 Berry, Bellaire, TX | 1941-06-20
(2 rows)
Ejercicios

1. Obtenga un listado (nombre y apellido, ordenado alfabéticamente por apellido) de los


empleados varones que ganan entre 30000 y 10000.
2. Obtenga un listado con los empleados (nombre, apellido) que tienen asignado más de
20 horas a un proyecto.
3. Obtenga los empleados que trabajan en un proyecto dirigido por un departamento
cuyo jefe es el empleado "Smith".
4. Encuentre los empleados que no están asignado a ningún proyecto.
5. Los empledados que tienen en alguno de sus proyectos las misma cantidad de horas
que tiene asignado el empleado NSS=12345678 al proyecto 1020.
6. Encuentre Los empleados que trabajan en los mismos proyectos que el empleado con
NSS=12345678
Funciones de agregación y de agrupación

1. Funciones de agregación
COUNT – Número de tuplas
SUM
MAX (MIN) – Se pueden usar en dominios no numéricos, si
existe un orden total entre los elementos
AVG
2. Funciones de agrupación
GROUP BY
Funciones de agregación

Encontrar la suma de todos los salarios de los empleados, el salario máximo, el salario
mínimo y el salario promedio
SELECT SUM(SALARIO),
MAX(SALARIO),
MIN(SALARIO),
AVG(SALARIO)
FROM EMPLEADO;

sum | max | min | avg


-----------+----------+----------+--------------------
281000.00 | 55000.00 | 25000.00 | 35125.000000000000
(1 row)
Funciones de agregación

Encontrar la suma de todos los salarios de los empleados del departamento de


investigación, así como el salario máximo, el salario mínimo y el salario promedio de dicho
departamento
SELECT SUM(SALARIO),
MAX(SALARIO),
MIN(SALARIO),
AVG(SALARIO)
FROM (EMPLEADO JOIN DEPARTAMENTO ON ND = NUMEROD)
WHERE NOMBRED= ’Investigacion’;

sum | max | min | avg


-----------+----------+----------+--------------------
133000.00 | 40000.00 | 25000.00 | 33250.000000000000
(1 row)
Funciones de agregación

Recupere el total de empleados de la empresa


SELECT COUNT(*) AS TOTAL_EMPLEADO
FROM EMPLEADO;

total_empleado
----------------
8
(1 row)

Recupere el total de empleados del departamento de investigación


SELECT COUNT(*)
FROM (EMPLEADO JOIN DEPARTAMENTO ON ND = NUMEROD)
WHERE NOMBRED= ’Investigacion’;

count
-------
4
(1 row)
Funciones de agregación

COUNT(*) – Número de filas


SELECT COUNT(DISTINCT SALARIO)
FROM EMPLEADO;

count
-------
6
(1 row)
Funciones de agregación

Recupere el nombre de los empleados que tienen más de dos cargas familiares
(dependientes)
SELECT APELLIDO, NOMBRE
FROM EMPLEADO
WHERE (SELECT COUNT(*)
FROM DEPENDIENTE
WHERE NSS=NSSE) >=2;

apellido | nombre
----------+----------
Smith | John
Worg | Franklin
(2 rows)
Funciones de agregación – GROUP BY

Por cada departamento, recupere el número del departamento, el total de empleado y el


salario medio
SELECT ND,
COUNT(*),
AVG(SALARIO)
FROM EMPLEADO
GROUP BY ND;

nd | count | avg
----+-------+--------------------
5 | 4 | 33250.000000000000
4 | 3 | 31000.000000000000
1 | 1 | 55000.000000000000
(3 rows)
Funciones de agregación – GROUP BY

De cada proyecto, recupere su número, nombre y el número de empleados que trabajan en


él
SELECT NUMEROP,
NOMBRE,
COUNT(*)
FROM (PROYECTO JOIN TRABAJA_EN ON NP = NUMEROP)
GROUP BY NUMEROP, NOMBRE;

numerop | nombre | count


---------+----------------+-------
1 | ProductoX | 2
10 | Automatizacion | 3
3 | ProductoZ | 2
30 | Nuevos Benefic | 3
2 | ProductoY | 3
20 | Reorganizacion | 3
(6 rows)
Funciones de agregación – GROUP BY y HAVING

De cada proyecto, en el que trabajen más de dos empleados, recupere su número, su


nombre y el número de empleados que trabajan en él
SELECT NUMEROP,
NOMBRE,
COUNT(*)
FROM (PROYECTO JOIN TRABAJA_EN ON NP = NUMEROP)
GROUP BY NUMEROP, NOMBRE
HAVING COUNT(*) > 2:

numerop | nombre | count


---------+----------------+-------
10 | Automatizacion | 3
30 | Nuevos Benefic | 3
2 | ProductoY | 3
20 | Reorganizacion | 3
(4 rows)
Funciones de agregación – GROUP BY y HAVING

De cada proyecto, recupere su número, su nombre y el número de empleados del


departamento 5 que trabajan en él
SELECT P.NUMEROP,
P.NOMBRE,
COUNT(*)
FROM ((PROYECTO AS P JOIN TRABAJA_EN ON NP = NUMEROP) JOIN EMPLEADO ON NSS=NSSE
WHERE ND = 5
GROUP BY P.NUMEROP, P.NOMBRE;

numerop | nombre | count


---------+----------------+-------
3 | ProductoZ | 2
1 | ProductoX | 2
20 | Reorganizacion | 1
10 | Automatizacion | 1
2 | ProductoY | 3
(5 rows)
Funciones de agregación – GROUP BY y HAVING

Por cada departamento con más de 5 empleados, obtener el total de empleados que ganen
más de 40.000 dólares
SELECT NOMBRED,
COUNT(*)
FROM (DEPARTAMENTO JOIN EMPLEADO ON ND = NUMEROD)
WHERE SALARIO > 40000 AND
ND IN (SELECT ND
FROM EMPLEADO
GROUP BY ND
HAVING COUNT(*) > 5)
GROUP BY NOMBRED;

nombred | count
---------+-------
(0 rows)
Resumen de las consultas en SQL

SELECT <atributos y listas de funciones>


FROM <lista de relaciones> (1)
[WHERE <condición>] (2)
[GROUP BY <atributo(s) de agrupación> ] (3)
[HAVING <condición de agrupación> ] (4)
[ORDER BY <lista de atributos> ] (5)
Sentencias INSERT, DELETE y UPDATE en SQL
Definición de tablas (DDL)

CREATE TABLE EMPLEADO (...


ND INT NOT NULL
CONSTRAINT CLESUPERVEMP
FOREIGN KEY (NSS_SUPERV) REFERENCES EMPLEADO (NSS)
ON DELETE SET NULL ON UPDATE CASCADE,
CONSTRAINT CLEDEPTOEMP
FOREIGN KEY (ND) REFERENCES DEPARTAMENTO (NUMEROD)
ON DELETE CASCADE ON UPDATE CASCADE);
INSERT

Forma simple

INSERT INTO EMPLEADO


VALUES (’John’, ’B’, ’Smith’, ’123456789’, ’01/09/1965’,
’731 Fondren, Houston, TX’, ’H’, 30000, ’333445555’,5);

Otra forma

INSERT INTO EMPLEADO(NOMBRE, APELLIDO, ND, NSS)


VALUES (’Gilberto’, ’G’, ’Gutierrez’, 4, ’8906080’),
(’Luis’,’L’, ’Salcedo’,5,’123456710’);

se debe tener en cuenta la forma en que se creó la tabla (NOT NULL, Integridad referencial,
de entidad)
INSERT (cont.)

Insertando tuplas a partir del resultado de una consulta


CREATE TABLE INFO_DEPTOS
(NOMBRE_DEPTO VARCHAR(15),
NUM_DE_EMPS INTEGER,
SAL_TOTAL INTEGER);

INSERT INTO INFO_DEPTOS (NOMBRE_DEPTO, NUM_DE_EMPS, SAL_TOTAL)


SELECT NOMBRED, COUNT(*), SUM(SALARIO)
FROM (DEPARTAMENTO JOIN EMPLEADO ON NUMEROD=ND)
GROUP BY NOMBRED;

SELECT * FROM INFO_DEPTOS;

nombre_depto | num_de_emps | sal_total


----------------+-------------+-----------
Direccion | 1 | 55000
Administracion | 3 | 93000
Investigacion | 4 | 133000
(3 rows)
DELETE

DELETE FROM EMPLEADO


WHERE APELLIDO =’Gutierrez’;

DELETE FROM EMPLEADO


WHERE NSS= ’8906080’;

DELETE FROM EMPLEADO


WHERE ND IN (SELECT NUMEROD
FROM DEPARTAMENTO
WHERE NOMBRED = ’Investigacion’);

DELETE FROM EMPLEADO;


UPDATE

Modificar los valores de los atributos en una o más tuplas


UPDATE PROYECTO
SET LOCALIZACIONP=’Bellaire’,
ND = 5
WHERE NUMEROP= 10;

UPDATE PROYECTO
SET SALARIO= SALARIO * 1.1
WHERE ND IN (SELECT NUMEROD
FROM DEPARTAMENTO
WHERE NOMBRED=’Investigacion’);

También se puede especificar NULL o DEFAULT como nuevo valor del atributo
Vistas (tablas virtuales) en SQL
Vistas
Vistas

Diferentes visiones de la Base de Datos


Consultas complejas.
Ejemplo “Los empleados del departamento 10 que ganan más
que el promedio de la empresa y menos que el promedio del
departamento 30”

Definición: Una vista en SQL es una tabla derivada de otras tablas o


relaciones, las cuales pueden ser:
tablas o relaciones de base
Vistas previamente definidas
Especificación de una vista en SQL

create view v as <expresión de consulta>


Ejemplo: “Los empleados del departamento de ’Investigación’ ”
CREATE VIEW INVESTIGACION AS
SELECT E.NSS, E.NOMBRE, E.INIC, E.APELLIDO, E.SALARIO
FROM (EMPLEADO E JOIN DEPARTAMENTO ON E.ND = NUMEROD)
WHERE NOMBRED = ’Investigacion’
ORDER BY E.APELLIDO, E.NOMBRE

CREATE VIEW
Ahora podemos consultar directamente la vista INVESTIGACION
SELECT * FROM INVESTIGACION;

nss | nombre | inic | apellido | salario


-----------+----------+------+----------+----------
453453453 | Joyce | A | English | 25000.00
666884444 | Ramesh | K | Narayan | 38000.00
123456789 | John | B | Smith | 30000.00
333445555 | Franklin | T | Worg | 40000.00
(4 rows)
Vistas

Ejemplo: “Una lista de empleados y su jefe


CREATE VIEW EMPYJEFES AS
SELECT E1.NOMBRE AS NOMBRE, E1.APELLIDO AS APELLIDO,
E2.NOMBRE AS NOMBRE_J, E2.APELLIDO AS APELLIDO_J
FROM (EMPLEADO E1 LEFT OUTER JOIN EMPLEADO E2 ON E1.NSS_SUPERV = E2.NSS);

CREATE VIEW

select * from empyjefes;


nombre | apellido | nombre_j | apellido_j
----------+----------+----------+------------
John | Smith | Franklin | Worg
Franklin | Worg | James | Borg
Alicia | Zelaya | Jennifer | Wallace
Jennifer | Wallace | James | Borg
Ramesh | Narayan | Franklin | Worg
Joyce | English | Franklin | Worg
Ahmad | Jabbar | Jennifer | Wallace
James | Borg | |
(8 rows)
Vistas

Por cada departamento queremos mantener un resumen con el total


de empleados y el salario total
CREATE VIEW RESUMEN(NOMBRE_DEPTO, TOTAL_EMPELADOS, TOTAL_SALARIO) AS
SELECT NOMBRED, COUNT(*), SUM(SALARIO)
FROM (EMPLEADO JOIN DEPARTAMENTO ON ND=NUMEROD)
GROUP BY NOMBRED
ORDER BY NOMBRED;

CREATE VIEW

select * from resumen;


nombre_depto | total_empelados | total_salario
----------------+-----------------+---------------
Administracion | 3 | 93000.00
Direccion | 1 | 55000.00
Investigacion | 4 | 133000.00
(3 rows)
Vistas

Las modificaciones en las tablas bases se ven reflejadas en la vista.


Esto es responsabilidad del SABD
Eliminación de una vista
DROP VIEW <nombre de la vista>
Implementación de vistas

1. Modificación de consulta. Convertir la consulta sobre las tablas


de base. Su principal desventaja es el tiempo de ejecución.
2. Materialización de vistas. Crear físicamente la tabla de vista
cuando se consulta la vista por primera vez y mantener la tabla
para aprovecharla en consultas posteriores. Esto implica contar
con estrategias para mantener actualizada la vista siendo una de
ella la actualización incremental.
Actualización de vistas

Muy complicada y ambigua.


insert into investigacion values(’1’, ’Juan’, ’JP’, ’Perez’, 5000);

Una vista con una sola tabla base es actualizable si los atributos
de la vista contienen la clave primaria o alguna otra clave
candidata de la relación base.
En general las vistas definidas sobre múltiples tablas por medio
de join no son actualizables.
Las vistas definidas mediante agrupación y funciones de
agregación no son actualizables.
Especificación de índices en SQL
Indices

CREATE TABLE EMPLEADO (


NOMBRE VARCHAR(15) NOT NULL,
INIC CHAR,
APELLIDO VARCHAR(15) NOT NULL,
NSS CHAR(9) NOT NULL,
FECHA_NCTO DATE,
DIRECCION VARCHAR(15),
SEXO CHAR,
SALARIO DECIMAL(10,2),
NSS_SUPERV CHAR(9),
ND INT NOT NULL,
PRIMARY KEY(NSS),
FOREIGN KEY(NSS-SUPERV) REFERENCES EMPLEADO (NSS),
FOREIGN KEY(ND) REFERENCES DEPARTAMENTO (NUMEROD));
SELECT * FROM EMPLEADO WHERE NSS=’123456789’; =⇒ todo bien, muy rápido
SELECT * FROM EMPLEADO WHERE salario=25000; =⇒ recorrer toda la tabla empleado,
tarda demasiado.
(salario es frecuentemente usado en la cláusula WHERE)
creación de un indices

CREATE INDEX SALARIOIDX ON EMPLEADO (SALARIO);


ggutierr=> \d empleado
Table "public.empleado"
Column | Type | Modifiers
------------+-----------------------+-----------
nombre | character varying(15) | not null
inic | character(1) |
apellido | character varying(15) | not null
nss | character(9) | not null
fecha_ncto | date |
direccion | character varying(30) |
sexo | character(1) |
salario | numeric(10,2) |
nss_superv | character(9) |
nd | integer | not null
Indexes:
"empleado_pkey" PRIMARY KEY, btree (nss)
"salarioidx" btree (salario)
creación de un índice

CREATE INDEX INICIDX ON EMPLEADO USING HASH (INIC);


ggutierr=> \d empleado
Table "public.empleado"
Column | Type | Modifiers
------------+-----------------------+-----------
nombre | character varying(15) | not null
inic | character(1) |
apellido | character varying(15) | not null
nss | character(9) | not null
fecha_ncto | date |
direccion | character varying(30) |
sexo | character(1) |
salario | numeric(10,2) |
nss_superv | character(9) |
nd | integer | not null
Indexes:
"empleado_pkey" PRIMARY KEY, btree (nss)
"inicidx" hash (inic)
"salarioidx" btree (salario)
Eliminación de un índice

DROP INDEX SALARIOIDX;


Procedimientos Almacenados de Bases
de Datos
Procedimientos almacenados y funciones

1. Lo normal es que el programa de aplicación de Bases de Datos se


ejecute en el cliente.
2. Sin embargo, a veces es conveniente crear módulos de programas
que se almacenen en lado del servidor (procedimientos
almacenados / módulos almacenados persistentes)

Los Procedimientos almacenados son útiles en los siguientes casos:


1. Varias aplicaciones accesan un mismo programa de bases de
datos. Se reduce la duplicidad de esfuerzo
2. Reducir el costo de derivado de la transferencia de datos
3. Potenciar las vistas (tipos de datos derivados más complejos)
Procedimientos almacenados y funciones

Declaración de un procedimiento almacenado


CREATE PROCEDURE hnombre del procedimientoi (hparámetrosi)
hdeclaraciones localesi
hcuerpo del procedimientoi;
Declaración de una función
CREATE FUNCTION hnombre de la funcióni (hparámetrosi)
RETURNS htipo de devolucióni
hdeclaraciones localesi
hcuerpo de la funcióni;
Declaración usando un lenguaje de propósito general
CREATE PROCEDURE hnombre del procedimientoi (hparámetrosi)
LANGUAGE hnombre del lenguaje de programacióni
EXTERNAL NAME hnombre de la ruta del archivoi;
Procedimientos almacenados y funciones

LLamando a un procedimiento almacenado o una función


1. CALL hnombre del procedimiento o funcióni(hlista de argumentos)i)
2. SELECT hnombre de la funcióni(hlista de argumentos)i), . . .
Ejemplo:
Procedimientos almacenados y funciones

Ejemplos usando Postgres


Una función para obtener la edad de un empleado
CREATE FUNCTION Edad(date, character(9))
RETURNS integer
AS ’SELECT ($1-fecha_ncto)/365 FROM empleado WHERE $2 = NSS;’
LANGUAGE ’sql’;

SELECT nombre, Apellido, Edad(’10/03/2008’, NSS) FROM Empleado;


nombre | apellido | edad
----------+----------+------
John | Smith | 43
Franklin | Worg | 52
Alicia | Zelaya | 40
Jennifer | Wallace | 67
Ramesh | Narayan | 46
Joyce | English | 36
Ahmad | Jabbar | 39
James | Borg | 70
Juan | Perez | 43
(9 rows)
Procedimientos almacenados y funciones

Ejemplos usando Postgres


SELECT Nombre, Apellido, Edad(’11/02/2008’, NSS) AS EDAD
FROM EMPLEADO
ORDER BY EDAD;

SELECT Nombre, Apellido, Edad(’11/02/2008’, NSS) AS EDAD


FROM EMPLEADO where Edad(’11/02/2008’,NSS) < 50
ORDER BY EDAD;

nombre | apellido | edad


--------+----------+------
Joyce | English | 36
Ahmad | Jabbar | 39
Alicia | Zelaya | 40
John | Smith | 43
Juan | Perez | 43
Ramesh | Narayan | 46
(6 rows)
Procedimientos almacenados y funciones

Ejemplos usando Postgres


Una función para obtener la cantidad de empleados de un departamento
CREATE FUNCTION TamDpto(integer)
RETURNS bigint
AS ’SELECT COUNT(*)
FROM EMPLEADO WHERE ND=$1;’
LANGUAGE ’sql’;

SELECT Nombred, tamdpto(numerod) FROM Departamento;


nombred | tamdpto
----------------+---------
Investigacion | 4
Administracion | 3
Direccion | 1
Nuevo Depto | 1
(4 rows)
Triggers de Bases de Datos (Bases de
Datos Activas)
Trigger

Trigger: Sentencia que el sistema ejecuta automáticamente como un


efecto secundario producto de una modificación en la base de datos
(INSERT, DELETE, UPDATE).
Modelo: ECA — (Evento, Condición, Acción)
1. Evento—Acción sobre la BD que provoca que trigger se dispare
(UPDATE, INSERT, DELETE, o eventos temporales)
2. Condición—Condiciones bajo las cuales se ejecuta la acción (if
new.saldo <= 0)
3. Acción—Secuencia de instrucciones que se ejecutan una vez
cumplido el evento y las condiciones. Normalmente una
secuencia de sentencias SQL, pero también una transacción o un
programa externo.
Triggers

Oracle:
CREATE TRIGGER nombre_regla
{BEFORE | AFTER }
{INSERT | DELETE | UPDATE [OF lista_atributos]}
ON nombre_relaci’on
[ REFERENCING [NEW | OLD] AS nombre_par’ametro]
[FOR EACH {ROW | STATEMENT} ]
[WHEN ( condici’on ) ]
{sentencia_SQL | procedimiento_SQL}
Triggers/ejemplos

EMPLEADO(Nombre, Dni, Sueldo, Dno, SuperDni)


DEPARTAMENTO(NombreDepto, Dno, SueldoTotal, DniDirector)
Eventos que afectan SueldoTotal:
1. Inserción (uno o más) de nuevas tuplas de empleado
2. Modificación del sueldo de los empleados existentes (uno o más)
3. Modificación de la asignación de de los empleados existentes de
un departamento a otro
4. Eliminación de tuplas de empleado (una o más)
Triggers/ejemplos

R1:
CREATE TRIGGER SueldoTotal1
AFTER INSERT ON EMPLEADO
FOR EACH ROW
WHEN (NEW.Dno IS NOT NULL)
UPDATE DEPARTAMENTO
SET SueldoTotal = SueldoTotal + NEW.Sueldo
WHERE Dno = NEW.Dno;
R2:
CREATE TRIGGER SueldoTotal2
AFTER UPDATE OF Sueldo ON EMPLEADO
FOR EACH ROW
WHEN (NEW.Dno IS NOT NULL)
UPDATE DEPARTAMENTO
SET SueldoTotal = SueldoTotal + NEW.Sueldo - OLD.Sueldo
WHERE Dno = NEW.Dno;
Triggers/ejemplos

R3:
CREATE TRIGGER SueldoTotal3
AFTER UPDATE OF Dno ON EMPLEADO
FOR EACH ROW
BEGIN
UPDATE DEPARTAMENTO
SET SueldoTotal = SueldoTotal + NEW.Sueldo
WHERE Dno = NEW.Dno;
UPDATE DEPARTAMENTO
SET SueldoTotal = SueldoTotal - OLD.Sueldo
WHERE Dno = Old.Dno;
END;
R4:
CREATE TRIGGER SueldoTotal4
AFTER DELETE ON EMPLEADO
FOR EACH ROW
WHEN (OLD.Dno IS NOT NULL)
UPDATE DEPARTAMENTO
SET SueldoTotal = SueldoTotal - OLD.Sueldo
WHERE Dno = Old.Dno;
Triggers/ejemplos

Articulo(codigo, Nombre, saldo, StockMinimo,precio)


Pedido(codigoArticulo, cantidad, fechaPedido)
Cada vez que haya una actualización del saldo, si el nuevo saldo es inferior al Stock mínimo,
entonces insertar una tupla en la tabla pedido
CREATE TRIGGER NuevoPedido
AFTER UPDATE OF saldo ON articulo
WHEN NEW.saldo < OLD.StockMinimo
FOR EACH ROW
BEGIN
INSERT INTO PEDIDO
VALUES (:OLD.cdigo, :OLD.StockMinimo, today())
END
Triggers

Ejemplo en postgres

You might also like