Você está na página 1de 104

Funciones a Nivel de Fila

1-1

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Objetivos
Al completar esta leccin, debera ser
capaz de hacer lo siguiente:

1-2

Explicar los diversos tipos de


funciones disponibles en SQL.

Incluir una variedad de funciones de


caracteres, numricas y de datos en
sentencias SELECT.

Explicar las funciones de conversin y


la manera en que podran ser usadas.
Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones SQL
Entrada

Salida

Funcin

arg 1
arg 2

Las Funciones
Realizan
Acciones

Valor
Resultado

arg n

1-3

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Dos Tipos de Funciones SQL

Funciones

Funciones a
Nivel de Fila

1-4

Funciones a
Nivel de
Mltiples Filas

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones a Nivel de Fila:


Sintaxis
Manipulan tems de datos.
Aceptan argumentos y devuelven un valor.
Actan sobre cada fila retornada.
Devuelven un resultado por fila.
Modifican el tipo de datos.
Pueden estar anidadas.

Sintaxis:
function_name
function_name (column|expression,
(column|expression, [arg1,
[arg1, arg2,...])
arg2,...])

1-5

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones a Nivel de Fila


Character

General

Conversion

1-6

Number

Single-row
functions

Date

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones de Caracteres
Funciones de
Caracteres

Funciones de Conversin

Funciones de
Manipulacin de Caracteres

LOWER
UPPER

CONCAT
SUBSTR

INITCAP

LENGTH
INSTR
LPAD

1-7

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones de Conversin
Conversin de cadenas de caracteres
Funcin

1-8

Resultado

LOWER('Curso SQL')

curso sql

UPPER ('Curso SQL')

CURSO SQL

INITCAP('Curso SQL')

Curso Sql

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de Funciones de Conversin


Visualizar el nmero de empleado,
nombre y n de departamento de Blake.
SQL>
SQL> SELECT
SELECT empno,
empno, ename,
ename, deptno
deptno
22 FROM
emp
FROM
emp
33 WHERE
ename
WHERE
ename == 'blake';
'blake';
no
no rows
rows selected
selected
SQL> SELECT
2 FROM
3 WHERE
EMPNO
EMPNO
----------------7698
7698
1-9

empno, ename, deptno


emp
LOWER(ename) = 'blake';

ENAME
DEPTNO
ENAME
DEPTNO
--------------------------- --------BLAKE
30
BLAKE
30
Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones de Manipulacin de
Caracteres
Manipulacin de cadenas de caracteres
Funcin

1-10

Resultado

CONCAT('Good', 'String')

GoodString

SUBSTR('String',1,3)

Str

LENGTH('String')

INSTR('String', 'r')

LPAD(sal,10,'*')

******5000

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de Funciones de
Manipulacin de Caracteres
SQL> SELECT ename, CONCAT (ename, job), LENGTH(ename),
2
INSTR(ename, 'A')
3 FROM
emp
SUBSTR(job,1,5) = 'SALES';
4 WHERE
ENAME
---------MARTIN
ALLEN
TURNER
WARD

1-11

CONCAT(ENAME,JOB)
LENGTH(ENAME) INSTR(ENAME,'A')
------------------- ------------- ---------------MARTINSALESMAN
6
2
ALLENSALESMAN
5
1
TURNERSALESMAN
6
0
WARDSALESMAN
4
2

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones Numricas
ROUND: Redondea un valor al decimal
especificado
ROUND(45.926, 2) 45.93
TRUNC:Trunca un valor en el decimal
especificado
TRUNC(45.926, 2) 45.92
MOD: Devuelve el resto de la divisin
MOD(1600, 300) 100
1-12

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Funcin ROUND


Visualizar el valor 45.923 redondeado a
centenas, 0, y 10 posiciones decimales.
SQL> SELECT ROUND(45.923,2), ROUND(45.923,0),
2
ROUND(45.923,-1)
3 FROM
SYS.DUAL;

ROUND(45.923,2) ROUND(45.923,0) ROUND(45.923,-1)


--------------- -------------- ----------------45.92
46
50

1-13

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Funcin TRUNC


Visualizar el valor 45.923 con TRUNC a
centenas, 0, y 10 posiciones decimales.
SQL> SELECT TRUNC(45.923,2), TRUNC(45.923),
2
TRUNC(45.923,-1)
3 FROM
SYS.DUAL;

TRUNC(45.923,2) TRUNC(45.923) TRUNC(45.923,-1)


--------------- ------------- --------------45.92
45
40

1-14

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Funcin MOD


Calcular el resto de dividir el salario entre
la comisin de cada empleado, cuyo
trabajo sea VENDEDOR.
SQL> SELECT
2 FROM
3 WHERE

ename, sal, comm, MOD(sal, comm)


emp
job = 'SALESMAN';

ENAME
SAL
COMM MOD(SAL,COMM)
---------- --------- --------- ------------MARTIN
1250
1400
1250
ALLEN
1600
300
100
TURNER
1500
0
1500
WARD
1250
500
250
1-15

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Trabajando con Fechas


Oracle almacena fechas en un formato numrico
interno.

Siglo, ao, mes, da, horas, minutos,


segundos.

El formato de fecha por defecto es DD-MON-YY.


SYSDATE es una funcin que devuelve fecha y
hora.

DUAL es una tabla virtual de la Base de Datos,


que puede ser usada para inspeccionar
SYSDATE.

1-16

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Operadores Aritmticos de
Fechas
Sumar o restar un nmero a de una
fecha da por resultado una fecha.

Restar dos fechas para encontrar la


cantidad de das entre esas fechas.

Sumar horas a una fecha dividiendo la


cantidad de horas por 24.

1-17

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de Operadores Aritmticos


en Fechas
SQL> SELECT ename, (SYSDATE-hiredate)/7 WEEKS
2 FROM
emp
3 WHERE deptno = 10;

ENAME
---------KING
CLARK
MILLER

1-18

WEEKS
--------830.93709
853.93709
821.36566

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones de Fecha

1-19

FUNCION

DESCRIPCION

MONTHS_BETWEEN

Nmero de meses entre dos


fechas

ADD_MONTHS

Agregar meses segn


calendario, a una fecha

NEXT_DAY

Prximo da de la fecha
especificada

LAST_DAY

Ultimo da del mes

ROUND

Redondea una fecha

TRUNC

Trunca una fecha

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de Funciones de Fecha


MONTHS_BETWEEN ('01-SEP-95','11-JAN-94')
19.6774194

1-20

ADD_MONTHS ('11-JAN-94',6)

'11-JUL-94'

NEXT_DAY ('01-SEP-95','FRIDAY')

'08-SEP-95'

LAST_DAY('01-SEP-95')

'30-SEP-95'

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de Funciones de Fecha

ROUND('25-JUL-95','MONTH')

01-AUG-95

ROUND('25-JUL-95','YEAR')

01-JAN-96

TRUNC('25-JUL-95','MONTH')

01-JUL-95

TRUNC('25-JUL-95','YEAR')

01-JAN-95

1-21

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones de Conversin
Conversin de
Tipos de Datos

Conversin
Implcita

1-22

Conversin
Explcita

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Conversin Implcita del Tipo de


Dato
Para asignaciones, Oracle automticamente
puede convertir:

1-23

De

VARCHAR2 o CHAR

NUMBER

VARCHAR2 o CHAR

DATE

NUMBER

VARCHAR2

DATE

VARCHAR2
Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Conversin Explcita del Tipo de


Dato
Para evaluar una expresin, Oracle
automticamente puede convertir:

1-24

De

VARCHAR2 o CHAR

NUMBER

VARCHAR2 o CHAR

DATE

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Conversin Explcita del Tipo de


Dato
TO_NUMBER

NUMBER

TO_CHAR

1-25

TO_DATE

CHARACTER

TO_CHAR

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

DATE

Funcin TO_CHAR con Fechas


TO_CHAR(date,
TO_CHAR(date, 'fmt')
'fmt')

El formato:

Debe estar encerrado entre comillas simples y


es sensible a maysculas/minsculas.

Puede incluir cualquier elemento de formato de


fecha vlido.

Tiene un elemento fm (fill mode) para eliminar

espacios en blanco de relleno o suprimir ceros


a la izquierda.

Est separado de la fecha por una coma.


1-26

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Elementos del Modelo Formato de Fecha

1-27

YYYY

Ao completo en nmero

YEAR

Ao en letras

MM

N del mes con dos dgitos

MONTH

Nombre completo del mes

DY

Abreviatura de tres letras del


da de la semana

DAY

Nombre completo del da


Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Elementos del Formato de


Fechas

Obtencin de la hora:

HH24:MI:SS AM

15:45:32 PM

Aadir cadenas de caracteres encerrndolas


entre dobles comillas.

DD "of" MONTH
12 of OCTOBER
Sufijo que permita obtener el n del da en letra.
ddspth

1-28

fourteenth

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Formato de Fecha RR
Ao Actual
1995
1995
2001
2001

Fecha Especficada
27-OCT-95
27-OCT-17
27-OCT-17
27-OCT-95

Formato RR
1995
2017
2017
1995

FormatoYY
1995
1917
2017
2095

Si los 2 dgitos especificados del ao estn


Si los 2
dgitos del
ao
corriente
estn

1-29

0-49

50-99

0-49

La fecha devuelta
corresponde al
siglo corriente.

La fecha devuelta
corresponde al siglo
anterior al corriente.

50-99

La fecha devuelta
corresponde al
siglo posterior al
corriente.

La fecha devuelta
corresponde al siglo
corriente.

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funcin TO_CHAR con Fechas


SQL> SELECT ename,
2
TO CHAR(hiredate, 'fmDD Month YYYY') HIREDATE
3 FROM
emp;
ENAME
HIREDATE
---------- ----------------KING
17 November 1981
BLAKE
1 May 1981
CLARK
9 June 1981
JONES
2 April 1981
MARTIN
28 September 1981
ALLEN
20 February 1981
...
14 rows selected.
1-30

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funcin TO_CHAR con Nmeros


TO_CHAR(number,
TO_CHAR(number, 'fmt')
'fmt')

Use estos formatos con la funcin


TO_CHAR para mostrar un carcter como
un nmero.

1-31

9
0

Representa un nmero
Fuerza a que se muestre el 0 (cero)

Signo del dlar

L
.
,

Usa el smbolo de moneda local


Imprime el punto decimal
Imprime el indicador de millar
Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la
Funcin TO_CHAR con Nmeros
SQL> SELECT
2 FROM
3 WHERE

TO_CHAR(sal,'$99,999') SALARY
emp
ename = 'SCOTT';

SALARY
-------$3,000

1-32

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones
TO_NUMBER y TO_DATE
Convierte una cadena de caracteres a
un formato numrico usando la funcin
TO_NUMBER
TO_NUMBER(char)
TO_NUMBER(char)

Convierte una cadena de caracteres a


un formato de fecha usando la funcin
TO_DATE
TO_DATE(char[,
TO_DATE(char[, 'fmt'])
'fmt'])
1-33

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

NVL Function
Convierte un nulo a un valor.
Los tipos de datos pueden ser de fecha,
cadenas de caracteres y nmeros.
Los tipos de datos deben coincidir:
NVL(comm,0)
NVL(hiredate,'01-JAN-97')
NVL(job,'No Job Yet')

1-34

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Funcin NVL


SQL> SELECT ename, sal, comm, (sal*12)+NVL(comm,0)
2 FROM
emp;
ENAME
SAL
COMM (SAL*12)+NVL(COMM,0)
---------- --------- --------- -------------------KING
5000
60000
BLAKE
2850
34200
CLARK
2450
29400
JONES
2975
35700
MARTIN
1250
1400
16400
ALLEN
1600
300
19500
...
14 rows selected.

1-35

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

La Funcin DECODE
Hace las veces de sentecias CASE o
IF-THEN-ELSE, para facilitar consultas
condicionales.
DECODE(col/expression,
DECODE(col/expression, search1,
search1, result1
result1
[,
[, search2,
search2, result2,...,]
result2,...,]
[,
[, default])
default])

1-36

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Funcin DECODE


SQL> SELECT job, sal,
2
DECODE(job, 'ANALYST'
3
'CLERK',
4
'MANAGER',
5
6
REVISED_SALARY
7 FROM
emp;

SAL*1.1,
SAL*1.15,
SAL*1.20,
SAL)

JOB
SAL REVISED_SALARY
--------- --------- -------------PRESIDENT
5000
5000
MANAGER
2850
3420
MANAGER
2450
2940
...
14 rows selected.
1-37

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Anudamiento de Funciones

Las funciones a nivel de fila pueden ser


anidadas hasta cualquier nivel.

Las funciones anidadas son evaluadas desde


el nivel ms profundo al nivel menos
profundo.

F3(F2(F1(col,arg1),arg2),arg3)
Paso 1 = Resultado 1
Paso 2 = Resultado 2
Paso 3 = Resultado 3

1-38

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones Anidadas
SQL> SELECT
2
3 FROM
4 WHERE

ename,
NVL(TO_CHAR(mgr),'No Manager')
emp
mgr IS NULL;

ENAME
NVL(TO_CHAR(MGR),'NOMANAGER')
---------- ----------------------------KING
No Manager

1-39

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Resumen
Use funciones para:
Realizar cculos sobre los datos
Modificar datos de forma individual
Manipular la salida de grupos de
registros
Alterar formatos de fecha en su
visualizacin
Convertir tipos de datos de columnas
1-40

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Visin General de la Prctica


Crear consultas que requieran el uso de

funciones numricas, de caracteres y de


fechas.

Usar concatenacin con funciones.


Escribir consultas case insensitive para probar
la utilidad de las funciones de caracteres.

Ejecutar clculos sobre aos y meses de


servicio para un empleado.

Determinar la fecha de revisin para un


empleado.

1-41

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Visualizacin de Datos
a partir de Varias Tablas

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Objetivos
Al completar esta leccin, debera ser
capaz de hacer lo siguiente:

1-43

Escribir sentencias SELECT para acceder a


los datos desde una o ms tablas usando
equality y non-equality joins (combinaciones
por igualdad y por desigualdad).

Visualizar datos que no se cumpliran


normalmente con una condicin de join
usando outer joins (uniones externas).

Combinar (Join) una tabla consigo misma.

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Obtencin de Datos de Mltiples Tablas


EMP
EMPNO
-----7839
7698
...
7934

DEPT
ENAME
----KING
BLAKE

... DEPTNO
... -----...
10
...
30

MILLER ...

10

DEPTNO
-----10
20
30
40

DNAME
---------ACCOUNTING
RESEARCH
SALES
OPERATIONS

EMPNO
EMPNO DEPTNO
DEPTNO LOC
LOC
---------------------- ------- -------7839
10
7839
10 NEW
NEW YORK
YORK
7698
30
CHICAGO
7698
30 CHICAGO
7782
10
7782
10 NEW
NEW YORK
YORK
7566
20
DALLAS
7566
20 DALLAS
7654
30
7654
30 CHICAGO
CHICAGO
7499
30
CHICAGO
7499
30 CHICAGO
...
...
14
14 rows
rows selected.
selected.
1-44

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

LOC
-------NEW YORK
DALLAS
CHICAGO
BOSTON

Qu es un JOIN?
Use un join para consultar datos de ms
de una tabla.
SELECT
SELECT
FROM
FROM
WHERE
WHERE

table.column,
table.column, table.column
table.column
table1,
table1, table2
table2
table1.column1
table1.column1 == table2.column2;
table2.column2;

Escriba la condicin de join en la


clasula WHERE.
Preceda el nombre de la columna con el
de la tabla, cuando el mismo nombre de
columna, aparezca en ms de una tabla.
1-45

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Producto Cartesiano
Se establece un producto cartesiano cuando:
Se omite una condicin de join.
Se define una condicin de join invlida.
Se combinan todas las filas de la primer
tabla con todas las filas de la segunda.

Para evitar un producto cartesiano, se debe

incluir siempre una condicin de join vlida en


la clusula WHERE.

1-46

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Generacin de un Producto
EMP (14 registros)
DEPT (4 registros)
Cartesiano
EMPNO ENAME ... DEPTNO
DEPTNO DNAME
LOC
EMPNO ENAME
----------- --------7839
7839 KING
KING
7698
7698 BLAKE
BLAKE
...
...
7934
7934 MILLER
MILLER

Producto
Cartesiano:
14*4=56 rows

1-47

... DEPTNO
...
... ----------...
10
...
10
...
30
...
30
...
...

10
10

DEPTNO DNAME
LOC
----------- ------------------- --------------10
10 ACCOUNTING
ACCOUNTING NEW
NEW YORK
YORK
20
20 RESEARCH
RESEARCH DALLAS
DALLAS
30
CHICAGO
30 SALES
SALES
CHICAGO
40
OPERATIONS
BOSTON
40 OPERATIONS BOSTON

ENAME
DNAME
ENAME
DNAME
----------------------------KING
ACCOUNTING
KING
ACCOUNTING
BLAKE
ACCOUNTING
BLAKE
ACCOUNTING
...
...
KING
RESEARCH
KING
RESEARCH
BLAKE
RESEARCH
BLAKE
RESEARCH
...
...
56
56 rows
rows selected.
selected.
Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Tipos de Join
Equijoin Non-equijoin Outer join Self join

1-48

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Qu es un Equijoin?
EMP

DEPT

EMPNO ENAME
DEPTNO
------ ------- ------7839 KING
10
7698 BLAKE
30
7782 CLARK
10
7566 JONES
20
7654 MARTIN
30
7499 ALLEN
30
7844 TURNER
30
7900 JAMES
30
7521 WARD
30
7902 FORD
20
7369 SMITH
20
...
14 rows selected.

Primary key
1-49

DEPTNO
------10
30
10
20
30
30
30
30
30
20
20
...
14 rows

DNAME
---------ACCOUNTING
SALES
ACCOUNTING
RESEARCH
SALES
SALES
SALES
SALES
SALES
RESEARCH
RESEARCH
selected.

Foreign key

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

LOC
-------NEW YORK
CHICAGO
NEW YORK
DALLAS
CHICAGO
CHICAGO
CHICAGO
CHICAGO
CHICAGO
DALLAS
DALLAS

Recuperacin de Registros con


Equijoins
SQL> SELECT
2
3 FROM
4 WHERE

emp.empno, emp.ename, emp.deptno,


dept.deptno, dept.loc
emp, dept
emp.deptno=dept.deptno;

EMPNO ENAME DEPTNO DEPTNO LOC


----- ------ ------ ------ --------7839 KING
10
10 NEW YORK
7698 BLAKE
30
30 CHICAGO
7782 CLARK
10
10 NEW YORK
7566 JONES
20
20 DALLAS
...
14 rows selected.

1-50

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Calificacin de
Nombres de Columna Ambiguos
Usar como prefijos los nombres de
tablas para calificar los nombres de
columnas que estn en varias tablas.

Mejorar el rendimiento usando como


prefijos los nombres de tablas.

Distinguir columnas que tienen


nombres idnticos pero pertenecen a
diferentes tablas usando alias de
columnas.

1-51

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Condiciones de Bsqueda
Adicionales Usando el Operador
EMP
DEPT
AND: Ejemplo
EMPNO ENAME
DEPTNO
------ ------- ------7839 KING
10
7698 BLAKE
30
7782 CLARK
10
7566 JONES
20
7654 MARTIN
30
7499 ALLEN
30
7844 TURNER
30
7900 JAMES
30
7521 WARD
30
7902 FORD
20
7369 SMITH
20
...
14 rows selected.

1-52

DEPTNO DNAME
------ --------10 ACCOUNTING
30 SALES
10 ACCOUNTING
20 RESEARCH
30 SALES
30 SALES
30 SALES
30 SALES
30 SALES
20 RESEARCH
20 RESEARCH
...
14 rows selected.

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

LOC
-------NEW YORK
CHICAGO
NEW YORK
DALLAS
CHICAGO
CHICAGO
CHICAGO
CHICAGO
CHICAGO
DALLAS
DALLAS

Uso de Alias de Tabla


Ayudan a simplificar las consultas
SQL> SELECT emp.empno, emp.ename, emp.deptno,
2
dept.deptno, dept.loc
3 FROM
emp, dept
4 WHERE emp.deptno=dept.deptno;

SQL> SELECT e.empno, e.ename, e.deptno,


2
d.deptno, d.loc
3 FROM
emp e, dept d
4 WHERE e.deptno=d.deptno;

1-53

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Combinando Ms de Dos Tablas


CUSTOMER

ORD

NAME
CUSTID
NAME
CUSTID
------------------------------JOCKSPORTS
100
JOCKSPORTS
100
TKB
101
TKB SPORT
SPORT SHOP
SHOP
101
VOLLYRITE
102
VOLLYRITE
102
JUST
TENNIS
103
JUST TENNIS
103
K+T
SPORTS
105
K+T SPORTS
105
SHAPE
106
SHAPE UP
UP
106
WOMENS
107
WOMENS SPORTS
SPORTS
107
...
...
...
...
99 rows
rows selected.
selected.

1-54

CUSTID
CUSTID ORDID
ORDID
------------- ------------101
610
101
610
102
611
102
611
104
612
104
612
106
601
106
601
102
602
ITEM
102
602
106
604
106 ORDID
604 ITEMID
ORDID
ITEMID
106
605
106 -----605 ------------ ------...
...
610
33
610
21
rows
selected.
21 rows selected.
611
11
611
612
11
612
601
11
601
602
11
602
...
...
64
64 rows
rows selected.
selected.

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Non-Equijoins
EMP

SALGRADE

EMPNO ENAME
SAL
------ ------- -----7839 KING
5000
7698 BLAKE
2850
7782 CLARK
2450
7566 JONES
2975
7654 MARTIN
1250
7499 ALLEN
1600
7844 TURNER
1500
7900 JAMES
950
...
14 rows selected.

1-55

GRADE LOSAL HISAL


----- ----- -----1
700
1200
2
1201
1400
3
1401
2000
4
2001
3000
5
3001
9999

el salario en la tabla
EMP, est entre el salario
ms bajo y el salario
ms alto de la tabla
SALGRADE

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Recuperacin de Registros con


Non-Equijoins
SQL>
2
3
4

SELECT
FROM
WHERE
BETWEEN

e.ename, e.sal, s.grade


emp e, salgrade s
e.sal
s.losal AND s.hisal;

ENAME
SAL
GRADE
---------- --------- --------JAMES
950
1
SMITH
800
1
ADAMS
1100
1
...
14 rows selected.

1-56

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Outer Joins
EMP
ENAME
----KING
BLAKE
CLARK
JONES
...

DEPT
DEPTNO
-----10
30
10
20

DEPTNO
-----10
30
10
20
...
40

DNAME
---------ACCOUNTING
SALES
ACCOUNTING
RESEARCH
OPERATIONS

No hay empleados en el
departamento OPERATIONS

1-57

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Outer Joins
Usar Outer Join para ver las filas que no
cumplen la condicin de join.
El operador de un Outer Join es el signo
ms (+).

1-58

SELECT
SELECT
FROM
FROM
WHERE
WHERE

table.column,
table.column, table.column
table.column
table1,
table1, table2
table2
table1.column(+)
table1.column(+) == table2.column;
table2.column;

SELECT
SELECT
FROM
FROM
WHERE
WHERE

table.column,
table.column, table.column
table.column
table1,
table1, table2
table2
table1.column
table1.column == table2.column(+);
table2.column(+);

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de Outer Joins


SQL>
2
3
4

SELECT
FROM
WHERE
ORDER BY

e.ename, d.deptno, d.dname


emp e, dept d
e.deptno(+) = d.deptno
e.deptno;

ENAME
DEPTNO DNAME
---------- --------- ------------KING
10 ACCOUNTING
CLARK
10 ACCOUNTING
...
40 OPERATIONS
15 rows selected.

1-59

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Self Joins
EMP (WORKER)
EMPNO
----7839
7698
7782
7566
7654
7499

ENAME
-----KING
BLAKE
CLARK
JONES
MARTIN
ALLEN

MGR
---7839
7839
7839
7698
7698

EMP (MANAGER)
EMPNO ENAME
----- -------7839
7839
7839
7698
7698

KING
KING
KING
BLAKE
BLAKE

MGR en la tabla WORKER es igual a


EMPNO en la tabla MANAGER
1-60

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Combinacin de una Tabla


Consigo Misma
SQL> SELECT worker.ename||' works for '||manager.ename
2 FROM
emp worker, emp manager
3 WHERE worker.mgr = manager.empno;
WORKER.ENAME||'WORKSFOR'||MANAG
WORKER.ENAME||'WORKSFOR'||MANAG
------------------------------------------------------------BLAKE
BLAKE works
works for
for KING
KING
CLARK
CLARK works
works for
for KING
KING
JONES
JONES works
works for
for KING
KING
MARTIN
MARTIN works
works for
for BLAKE
BLAKE
...
...
13
13 rows
rows selected.
selected.

1-61

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Resumen
SELECT
SELECT
FROM
FROM
WHERE
WHERE

table.column,
table.column, table.column
table.column
table1,
table1, table2
table2
table1.column1
table1.column1 == table2.column2;
table2.column2;

Equijoin Non-equijoin Outer join Self join

1-62

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Datos Agregados por medio


de Funciones de Grupo

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Objetivos
Al completar esta leccin, debera ser
capaz de hacer lo siguiente:

1-64

Identificar las funciones de grupo


disponibles.

Explicar el uso de las funciones de


grupo.

Mostrar estadsticas para diferentes


grupos usando la clusula GROUP BY.

Incluir o excluir filas agrupadas usando


la clusula HAVING.
Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Qu son las Funciones de


Las Funciones de Grupo operan sobre conjuntos
Grupo?
de registros para dar
un resultado a nivel de grupo.
EMP
DEPTNO
SAL
--------- --------10
2450
10
5000
10
1300
20
800
20
1100
20
3000
20
3000
20
2975
30
1600
30
2850
30
1250
30
950
30
1500
30
1250
1-65

mximo salario
en la tabla EMP

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

MAX(SAL)
--------5000

Tipos de Funciones de Grupo


AVG ([DISTINCT|ALL]n)
COUNT ({ *|[DISTINCT|ALL]expr})
MAX ([DISTINCT|ALL]expr)
MIN ([DISTINCT|ALL]expr)
STDDEV ([DISTINCT|ALL]x)
SUM ([DISTINCT|ALL]n)
VARIANCE ([DISTINCT|ALL]x)
1-66

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Tipos de Funciones de Grupo


AVG ([DISTINCT|ALL]n)
COUNT ({ *|[DISTINCT|ALL]expr})
MAX ([DISTINCT|ALL]expr)
MIN ([DISTINCT|ALL]expr)
STDDEV ([DISTINCT|ALL]x)
SUM ([DISTINCT|ALL]n)
VARIANCE ([DISTINCT|ALL]x)
1-67

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de las Funciones AVG y


SUM

Puede usar AVG y SUM para datos numricos.


SQL> SELECT
2
3 FROM
4 WHERE

AVG(sal), MAX(sal),
MIN(sal), SUM(sal)
emp
job LIKE 'SALES%';

AVG(SAL) MAX(SAL) MIN(SAL) SUM(SAL)


-------- --------- --------- --------1400
1600
1250
5600

1-68

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de las Funciones MIN y


MAX

Puede usar MIN y MAX para cualquier tipo


de dato.
SQL> SELECT
2 FROM

MIN(hiredate), MAX(hiredate)
emp;

MIN(HIRED MAX(HIRED
--------- --------17-DEC-80 12-JAN-83

1-69

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Funcin COUNT


COUNT(*) devuelve el n de registros en
una tabla.
SQL> SELECT
2 FROM
3 WHERE

COUNT(*)
emp
deptno = 30;

COUNT(*)
--------6

1-70

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Funcin COUNT


COUNT(expr) devuelve el n de registros
no nulos en una tabla.
SQL> SELECT
2 FROM
3 WHERE

COUNT(comm)
emp
deptno = 30;

COUNT(COMM)
----------4

1-71

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Funciones de Grupo y Val. Nulos


Las Funciones de Grupo ignoran los
valores nulos de las columnas.
SQL> SELECT AVG(comm)
2 FROM
emp;

AVG(COMM)
--------550

1-72

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Funcin NVL con


Funciones de Grupo
La Funcin NVL fuerza a las funciones de
grupo a incluir valores nulos (null).
SQL> SELECT AVG(NVL(comm,0))
2 FROM
emp;

AVG(NVL(COMM,0))
---------------157.14286

1-73

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Creando Grupos de Datos


EMP
DEPTNO
SAL
--------- --------10
2450
10
5000
10
1300
20
800
20
1100
20
3000
20
3000
20
2975
30
1600
30
2850
30
1250
30
950
30
1500
30
1250
1-74

2916.6667

media de
DEPTNO AVG(SAL)
salarios
------- --------en
EMP
2175
10 2916.6667
para cada
20
2175
departamento
30 1566.6667
1566.6667

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Creando Grupos de Datos:


La Clusula GROUP BY
SELECT
FROM
[WHERE
[GROUP BY
[ORDER BY

column, group_function
table
condition]
group_by_expression]
column];

Divide los registros de una tabla en grupos


ms pequeos, por medio de GROUP BY.

1-75

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Clusula GROUP BY


Todas las columnas mencionadas en la
SELECT que no son funciones de grupo,
tienen que estar en la clusula GROUP BY.
SQL> SELECT
deptno, AVG(sal)
2 FROM
emp
3 GROUP BY deptno;

DEPTNO AVG(SAL)
--------- --------10 2916.6667
20
2175
30 1566.6667
1-76

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Clusula GROUP BY


La columna referencia por GROUP BY no
es necesario seleccionarla.
SQL> SELECT
AVG(sal)
2 FROM
emp
3 GROUP BY deptno;

AVG(SAL)
--------2916.6667
2175
1566.6667

1-77

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

EMP
DEPTNO
--------10
10
10
20
20
20
20
20
30
30
30
30
30
30
1-78

Agrupacin por Ms de Una


Columna
JOB
SAL
--------- --------MANAGER
2450
DEPTNO
PRESIDENT
5000
-------CLERK
1300
10
CLERK
800 suma de salarios
10
CLERK
1100
de EMP para
10
ANALYST
3000 cada oficio (job),
20
agrupado por
ANALYST
3000
20
departamento
MANAGER
2975
20
SALESMAN
1600
30
MANAGER
2850
30
SALESMAN
1250
30
CLERK
950
SALESMAN
1500
SALESMAN
1250
Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

JOB
SUM(SAL)
--------- --------CLERK
1300
MANAGER
2450
PRESIDENT
5000
ANALYST
6000
CLERK
1900
MANAGER
2975
CLERK
950
MANAGER
2850
SALESMAN
5600

Uso de la Clusula GROUP BY


sobre Mltiples Columnas
SQL> SELECT
deptno, job, sum(sal)
2 FROM
emp
3 GROUP BY deptno, job;

DEPTNO JOB
SUM(SAL)
--------- --------- --------10 CLERK
1300
10 MANAGER
2450
10 PRESIDENT
5000
20 ANALYST
6000
20 CLERK
1900
...
9 rows selected.
1-79

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Consultas No vlidas
Usando Funciones de Grupo
Cualquier columna o expresin en la
SELECT que no sea una funcin agregada,P BY
U
O
tiene que ser especificada en la clusula
R
G
GROUP BY.
a
ul
SQL>
SQL>
22

1-80

SELECT
SELECT
FROM
FROM

deptno,
deptno, COUNT(ename)
COUNT(ename)
la
emp;
emp;
n

s
u
cl

e
a
d
a
SELECT
deptno,
COUNT(ename)
SELECT deptno, COUNT(ename) ic
if
**
c
e
p
ERROR
at
line
1:
ERROR at line 1:
s
e
ORA-00937:
group
ORA-00937: not
not aa single-group
single-group
group function
function
O
N
a
n
m
u
JavierlBalbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002
o
C

Consultas No vlidas
Usando Funciones de Grupo
No puede usar una clusula WHERE para restringir
grupos.
Utilice la clusula HAVING para restringir grupos.
E
R
SQL>
deptno,
SQL> SELECT
SELECT
deptno, AVG(sal)
AVG(sal)
HE
22 FROM
emp
W
FROM
emp
a
l
33 WHERE
AVG(sal)
u
WHERE
AVG(sal) >> 2000
2000
s
u
44 GROUP
GROUP BY
BY deptno;
deptno;

l
c os
a
l up
r
WHERE
a gr
WHERE AVG(sal)
AVG(sal) >> 2000
2000
s
u ir
**
e
g
d
n
ERROR
e tr i
ERROR at
at line
line 3:
3:
u
p es is
ORA-00934:
ORA-00934: group
groupofunction
function
is not
not allowed
allowed here
here
r
N ra
1-81
Javier Balbuena
pa/ Jos Manuel Ferrer. Curso 2.001 / 2.002

Exclusin de Resultados de un
EMP
Grupo
DEPTNO
SAL
--------- --------10
2450
10
5000
10
1300
20
800
20
1100
20
3000
20
3000
20
2975
30
1600
30
2850
30
1250
30
950
30
1500
30
1250
1-82

5000
mximo salario
por departamento
3000 mayor de 2900$

DEPTNO MAX(SAL)
--------- --------10
5000
20
3000

2850

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Exclusin de Resultados de un
Grupo:
Use la clusula
Clusula
HAVING
HAVING
para restringir grupos:
Los registros son agrupados.
Se aplica la funcin de grupo.
Los grupos que se corresponden con la

clusula HAVING se visualizan.


SELECT
FROM
[WHERE
[GROUP BY
[HAVING
[ORDER BY
1-83

column, group_function
table
condition]
group_by_expression]
group_condition]
column];
Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Clusula HAVING


SQL>
2
3
4

SELECT
FROM
GROUP BY
HAVING

deptno, max(sal)
emp
deptno
max(sal)>2900;

DEPTNO MAX(SAL)
--------- --------10
5000
20
3000

1-84

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de la Clusula HAVING


SQL>
2
3
3
4
5

SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY

job, SUM(sal) PAYROLL


emp
job NOT LIKE 'SALES%'
job
SUM(sal)>5000
SUM(sal);

JOB
PAYROLL
--------- --------ANALYST
6000
MANAGER
8275

1-85

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Anidamiento de Funciones de
Grupo
Visualizar la mxima media de salarios por
departamento:

SQL> SELECT
max(avg(sal))
2 FROM
emp
3 GROUP BY deptno;
MAX(AVG(SAL))
------------2916.6667

1-86

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Resumen
SELECT
FROM
[WHERE
[GROUP BY
[HAVING
[ORDER BY

1-87

column, group_function
table
condition]
group_by_expression]
group_condition]
column];

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Subconsultas

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Objetivos
Al completar esta leccin, debera ser
capaz de hacer lo siguiente:
Describir los tipos de problemas que las
subconsultas pueden resolver.
Definir subconsultas.
Enumerar los tipos de subconsultas.
Escribir subconsultas que afecten a un
solo registro, o a ms de uno.
1-89

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de una Subconsulta para


Resolver un Problema
Quin tiene un salario superior al de Jones?
Consulta Principal

Qu empleados tienen un salario


superior al salrio de Jones?
Subconsulta

1-90

Cul es el salario de Jones?

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Subconsultas
SELECT
FROM
WHERE

select_list
table
expr operator
(SELECT
FROM

select_list
table);

La subconsulta se ejecuta una vez y


antes de la consulta principal.

El resultado de la subconsulta es usado


por la consulta principal externa.

1-91

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Usando una Subconsulta


SQL> SELECT ename
2 FROM
emp
2975
3 WHERE sal >
4
(SELECT sal
5
FROM
emp
6
WHERE empno=7566);
ENAME
ENAME
------------------KING
KING
FORD
FORD
SCOTT
SCOTT

1-92

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Gua para el Uso de


Subconsultas
Encierre las
subconsultas entre parntesis.
Una subconsulta debe aparecer a la
derecha del operador.
No aada una clusula ORDER BY a una
subconsulta.
Utilice operadores a nivel de fila para
subconsultas que devuelvan solo una fila.
Utilice operadores que actan sobre
varios registros para subconsultas que
devuelvan ms de una fila.
1-93

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Tipos de Subconsultas
Subconsulta mono-registro
Cons. Principal
Subquery

devuelve

CLERK

Subconsulta multi-registro
Cons. Principal
Subquery

devuelve

CLERK
MANAGER

Subconsulta multi-columna
Cons. Principal
Subquery
1-94

devuelve

CLERK
7900
MANAGER 7698

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Subconsultas Mono-registro
Devuelven un nico registro.
Se utilizan operadores de comparacin.
Operador

1-95

Significado

Igual a

>

Mayor que

>=

Mayor que o igual a

<

Menor que

<=

Menor que o igual a

<>

No igual a

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Ejecucin de Subc. Mono-registro


SQL>
2
3
4
5
6
7
8
9
10

SELECT
FROM
WHERE

AND

ENAME
ENAME
------------------MILLER
MILLER

1-96

ename, job
emp
job =
(SELECT
FROM
WHERE
sal >
(SELECT
FROM
WHERE

CLERK

job
emp
empno = 7369)
1100

sal
emp
empno = 7876);

JOB
JOB
----------------CLERK
CLERK

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso de Funciones de Grupo


en una Subconsulta

1-97

SQL> SELECT
2 FROM
3 WHERE
4
5

ename, job, sal


emp
sal =
(SELECT
FROM

ENAME
ENAME
------------------SMITH
SMITH

JOB
SAL
JOB
SAL
----------------- ----------------CLERK
800
CLERK
800

800

MIN(sal)
emp);

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

La Clusula HAVING en
Subconsultas

El Servidor Oracle8 ejecuta primero las


subconsultas.
El Servidor Oracle8 devuelve el
resultado a la clusula HAVING de la
consulta principal.
SQL>
2
3
4
5
6
7
1-98

SELECT
FROM
GROUP BY
HAVING

deptno, MIN(sal)
emp
deptno
MIN(sal) >
(SELECT
FROM
WHERE

800

MIN(sal)
emp
deptno = 20);

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Qu est mal en esta


Sentencia?
SQL> SELECT empno, ename
2 FROM
emp
3 WHERE sal =
4
(SELECT
5
FROM
6
GROUP BY

o
r
t
is
g
e
r
ti
l
u
m

ta
l
MIN(sal)
u
s
n
emp
o
deptno);bc
su
en
ro
ERROR:
t
ERROR:
s
i
ORA-01427:
single-row
subquery
returns
ORA-01427: single-row subquery greturns more
more than
than
e
one
r
one row
row
o
n
o
no
no rows
rows selected
selected
m
r
o
d
a
r
e
p
1-99
Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002
O

Funcionara esta Sentencia?


SQL> SELECT ename,
2 FROM
emp
3 WHERE job =
4
5
6
no
no rows
rows selected
selected

1-100

job

s
o
tr
s
i
g
re

e
v
l
(SELECT job
e
u
FROM
emp
v
e
d
WHERE
ename='SMYTHE');
O
N
ta
l
u
s
n
o
c
b
Su
La

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Subconsultas Multi-registro
Devuelven ms de un registro.
Use comparadores multi-registro.
Operador
IN

Igual a los valores de cierta lista

ANY

Compara los valores con cada valor


devuelto por la subconsulta

ALL

1-101

Significado

Compara los valores con cada uno de los


valores devueltos por la subconsulta

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso del Operador ANY en


Subconsultas Multi-registro
SQL>
2
3
4
5
6
7

SELECT
FROM
WHERE

AND

EMPNO
EMPNO
----------------7654
7654
7521
7521

1-102

empno, ename, job 1300


1100
emp
800
sal < ANY
950
(SELECT
sal
FROM
emp
WHERE
job = 'CLERK')
job <> 'CLERK';

ENAME
ENAME
------------------MARTIN
MARTIN
WARD
WARD

JOB
JOB
----------------SALESMAN
SALESMAN
SALESMAN
SALESMAN

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Uso del Operador ALL en


Subconsultas Multi-registro
SQL> SELECT
2 FROM
3 WHERE
4
5
6
EMPNO
EMPNO
----------------7839
7839
7566
7566
7902
7902
7788
7788
1-103

empno, ename, job 1566.6667


2175
emp
2916.6667
sal > ALL
(SELECT
avg(sal)
FROM
emp
GROUP BY
deptno)

ENAME
ENAME
------------------KING
KING
JONES
JONES
FORD
FORD
SCOTT
SCOTT

JOB
JOB
----------------PRESIDENT
PRESIDENT
MANAGER
MANAGER
ANALYST
ANALYST
ANALYST
ANALYST

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Resumen
Las Subconsulas resultan muy tiles
cuando una consulta esta basada en
valores que no conocemos.
SELECT
FROM
WHERE

1-104

select_list
table
expr operator
(SELECT select_list
FROM
table);

Javier Balbuena / Jos Manuel Ferrer. Curso 2.001 / 2.002

Você também pode gostar