Sei sulla pagina 1di 51

Material de Clase SQL

Unidad 4. Consultas multitabla (I)


4.1. Introduccin
Hasta ahora hemos visto consultas que obtienen los datos de una sola tabla, en este tema veremos
cmo obtener datos de diferentes tablas.
En esta parte ampliaremos la clusula FROM y descubriremos nuevas palabras reservadas (UNION,
EXCEPT e INTERSECT) que corresponden a operaciones relacionales.
Para obtener datos de varias tablas tenemos que combinar estas tablas mediante alguna
operacin basada en el lgebra relacional.
El lgebra relacional define una serie de operaciones cuyos operandos son tablas y cuyo resultado
es tambin una tabla.
Las operaciones de lgebra relacional implementadas en Transact-Sql son:
La unin UNION
La diferencia EXCEPT
La interseccin INTERSECT
El producto cartesiano CROSS JOIN
La composicin interna INNER JOIN
La composicin externa LEFT JOIN, RIGHT JOIN Y FULL JOIN
En todo el tema cuando hablemos de tablas nos referiremos tanto a las tablas que fsicamente
estn almacenadas en la base de datos como a las tablas temporales y a las resultantes de una
consulta o vista.

4.2. La unin de tablas UNION


La unin de tablas consiste en coger dos tablas y obtener una tabla con las filas de las dos tablas,
en el resultado aparecern las filas de una tabla y, a continuacin, las filas de la otra tabla.
Para poder realizar la operacin, las dos tablas tienen que tener el mismo esquema (mismo
nmero de columnas y tipos compatibles) y la tabla resultante hereda los encabezados de la
primera tabla.
La sintaxis es la siguiente:
{< consulta >|(< consulta >)}
UNION [ALL]
{< consulta >|(< consulta >)}
[{UNION [ALL] {< consulta >|(< consulta >)}}[ ...n ] ]
[ORDER BY {expression_columna|posicion_columna [ASC|DESC]}

Ing. Jos Rodrguez Mantilla

Pgina 1

Material de Clase SQL


[ ,...n ]]
< consulta > representa la especificacin de la consulta que nos devolver la tabla a combinar.
Puede ser cualquier especificacin de consulta con la limitacin de que no admite la clusula
ORDER BY, los alias de campo se pueden definir pero slo tienen efecto cuando se indican en la
primera consulta ya que el resultado toma los nombres de columna de esta.
Ejemplo: Suponemos que tenemos una tabla Valencia con las nuevas oficinas de Valencia y otra
tabla Madrid con las nuevas oficinas de Madrid y queremos obtener una tabla con las nuevas
oficinas de las dos ciudades:
SELECT oficina as OFI, ciudad FROM Valencia
UNION ALL
SELECT oficina, ciudad FROM Madrid;
El resultado sera:
OFI

ciudad

11

Valencia

28

Valencia

23

Madrid

El resultado coge los nombres de columna de la primera consulta y aparecen primero las filas de la
primera consulta y despus las de la segunda.
Si queremos que el resultado aparezca ordenado podemos incluir la clusula ORDER BY, pero
despus de la ltima especificacin de consulta, y expresion_columna ser cualquier columna
vlida de la primera consulta.
SELECT oficina as OFI, ciudad FROM Valencia
UNION
SELECT oficina, ciudad FROM Madrid
ORDER BY ofi;
OFI

ciudad

11

Valencia

23

Madrid

28

Valencia

Ahora las filas aparecen ordenadas por el nmero de oficina y hemos utilizado el nombre de
columna de la primera consulta.
Cuando aparezcan en el resultado varias filas iguales, el sistema por defecto elimina las
repeticiones.
Si se especifica ALL, el sistema devuelve todas las filas resultante de la unin incluidas las repetidas

Ing. Jos Rodrguez Mantilla

Pgina 2

Material de Clase SQL


El empleo de ALL tambin hace que la consulta se ejecute ms rpidamente ya que el sistema no
tiene que eliminar las repeticiones.
Se pueden combinar varias tablas con el operador UNION. Por ejemplo supongamos que tenemos
otra tabla Pamplona con las oficinas nuevas de Pamplona:
SELECT oficina, ciudad FROM Valencia
UNION
SELECT oficina, ciudad FROM Madrid
UNION
SELECT oficina, ciudad FROM Pamplona;
Combinamos las tres tablas.
Otro ejemplo:
Obtener todos los productos cuyo precio exceda de 20 o que se haya vendido ms de 300 euros
del producto en algn pedido.
SELECT idfab, idproducto
FROM productos
WHERE precio > 20
UNION
SELECT fab, producto
FROM pedidos
WHERE importe > 300;

4.3. La diferencia EXCEPT


Aparecen en la tabla resultante las filas de la primera consulta que no aparecen en la segunda.
Las condiciones son las mismas que las de la unin.
{<consulta>|(<consulta>)}
EXCEPT
{<consulta>|(<consulta>)}
[{EXCEPT {<consulta>|(<consulta>)}}[ ...n ] ]
[ORDER BY {expression_columna|posicion_columna [ASC|DESC]}
[ ,...n ]]
Por ejemplo tenemos las tablas T1 y T2.
T1

Ing. Jos Rodrguez Mantilla

T2

Pgina 3

Material de Clase SQL


Cod
Codigo
1
2
2
3
4
4
5
5
6

SELECT cod FROM T1


EXCEPT
SELECT codigo FROM T2;
Devuelve:
Cod
1
6

Ejemplo:
Listar los productos que no aparezcan en ningn pedido.
SELECT idfab, idproducto
FROM productos
EXCEPT
SELECT DISTINCT fab, producto
FROM pedidos;
Para practicar puedes realizar este Ejercicio La diferencia EXCEPT.
Nota: Para realizar los ejercicios, utiliza la base de datos Gestion (el archivo fsico se llamaba
GestionA) y GestionSimples.

Objetivo
Comparar dos tablas y crear un listado resultante de la comparacin. Los registros mostrados
sern los que tengan en comn.

Ejercicio paso a paso


Ing. Jos Rodrguez Mantilla

Pgina 4

Material de Clase SQL


Obtener los empleados de GestionSimples que aparecen en Gestion con misma oficina.
SELECT numemp, oficina
FROM gestionsimples.dbo.empleados
INTERSECT
SELECT numemp, oficina
FROM gestion.dbo.empleados;
Resultado:
Numemp oficina
101

12

102

21

103

12

104

12

105

13

106

11

107

22

108

21

109

NULL

110

NULL

111

NULL

112

NULL

113

NULL

4.5. La composicin de tablas


Hasta ahora hemos operado con tablas que tenan el mismo esquema, pero muchas veces lo que
necesitamos es obtener una tabla que tenga en una misma fila datos de varias tablas, por ejemplo,
obtener las facturas y que en la misma fila de factura aparezca el nombre y direccin del cliente.
Pues en lo que queda del tema estudiaremos este tipo de consultas basadas en la composicin de
tablas. La composicin de tablas consiste en obtener a partir de dos tablas cualquiera una nueva
tabla fusionando las filas de una con las filas de la otra, concatenando los esquemas de ambas
tablas. Consiste en formar parejas de filas.

Ing. Jos Rodrguez Mantilla

Pgina 5

Material de Clase SQL


La sentencia SELECT permite realizar esta composicin, incluyendo dos o ms tablas en la clusula
FROM.
Es hora de ampliar la clusula FROM que vimos en el tema anterior.
Empezaremos por estudiar la operacin a partir de la cual estn definidas las dems operaciones
de composicin de tabla, el producto cartesiano.

4.6. El producto cartesiano CROSS JOIN


El producto cartesiano obtiene todas las posibles concatenaciones de filas de la primera tabla con
filas de la segunda tabla.
Se indica escribiendo en la clusula FROM los nombres de las tablas separados por una coma o
utilizando el operador CROSS JOIN.
FROM {<tabla_origen>} [ ,...n ]
|<tabla_origen> CROSS JOIN <tabla_origen>
Tabla_origen puede ser un nombre de tabla o de vista o una tabla derivada (resultado de una
SELECT), en este ltimo caso la SELECT tiene que aparecer entre parntesis y la tabla derivada
debe llevar asociado obligatoriamente un alias de tabla. Tambin puede ser una co mposicin de
tablas.
Se pueden utilizar hasta 256 orgenes de tabla en una instruccin, aunque el lmite vara en funcin
de la memoria disponible y de la complejidad del resto de las expresiones de la consulta. Tambin
se puede especificar una variable table como un origen de tabla.
Ejemplo:
SELECT *
FROM empleados, oficinas;
Si ejecutamos esta consulta veremos que las filas del resultado estn formadas por las columnas
de empleados y las columnas de oficinas. En las filas aparece cada empleado combinado c on la
primera oficina, luego los mismos empleados combinados con la segunda oficina y as hasta
combinar todos los empleados con todas las oficinas.
Si ejecutamos:
SELECT *
FROM empleados CROSS JOIN oficinas;
Obtenemos lo mismo.
Este tipo de operacin no es la que se utiliza ms a menudo, lo ms frecuente sera combinar cada
empleado con los datos de SU oficina. Lo podramos obtener aadiendo a la consulta un WHERE
para filtrar los registros correctos:

Ing. Jos Rodrguez Mantilla

Pgina 6

Material de Clase SQL


SELECT *
FROM empleados, oficinas
WHERE empleados.oficina=oficinas.oficina;
Aqu nos ha aparecido la necesidad de cualificar los campos ya que el nombre oficina es un campo
de empleados y de oficinas por lo que si no lo cualificamos, el sistema nos da error.
Hemos utilizado en la lista de seleccin *, esto nos recupera todas las columnas de las dos tablas.
SELECT empleados.*,ciudad, region
FROM empleados, oficinas
WHERE empleados.oficina=oficinas.oficina;
Recupera todas las columnas de empleados y las columnas ciudad y regin de oficinas.
Tambin podemos combinar una tabla consigo misma, pero en este caso hay que definir un alias
de tabla, en al menos una, sino el sistema da error ya que no puede nombrar los campos.
SELECT *
FROM oficinas, oficinas as ofi2;
No insistiremos ms sobre el producto cartesiano porque no es la operacin ms utilizada, ya que
normalmente cuando queramos componer dos tablas lo haremos con una condicin de seleccin
basada en campos de combinacin y para este caso es ms eficiente el JOIN que veremos a
continuacin.
Para practicar puedes realizar este Ejercicio El producto cartesiano CROSS JOIN.
Nota: Para realizar los ejercicios, utiliza la base de datos GestionSimples.

Objetivo
Combinar datos de dos tablas en una nica tabla.

Ejercicio paso a paso


Listar los empleados que tienen una cuota superior al objetivo de al menos una oficina. La oficina
puede ser cualquiera no tiene por que ser la del empleado.
SELECT numemp, nombre, cuota, empleados.oficina AS [Su oficina], oficinas.oficina, objetivo
FROM empleados, oficinas
WHERE cuota > objetivo
Recuerda que se puede utilizar la coma para separar las tablas, ya que esto equivale a escribir
CROSS JOIN.
Resultado:

Ing. Jos Rodrguez Mantilla

Pgina 7

Material de Clase SQL


Numemp

Nombre

Cuota

Su oficina Oficina Objetivo

101

Antonio Viguer

30000,00

12

24

25000,00

101

Antonio Viguer

30000,00

12

29

10000,00

101

Antonio Viguer

30000,00

12

30

20000,00

102

Alvaro Jaumes

35000,00

21

22

30000,00

102

Alvaro Jaumes

35000,00

21

24

25000,00

102

Alvaro Jaumes

35000,00

21

29

10000,00

102

Alvaro Jaumes

35000,00

21

30

20000,00

103

Juan Rovira

27500,00

12

24

25000,00

103

Juan Rovira

27500,00

12

29

10000,00

103

Juan Rovira

27500,00

12

30

20000,00

104

Jos Gonzlez

20000,00

12

29

10000,00

105

Vicente Pantalla

35000,00

13

22

30000,00

105

Vicente Pantalla

35000,00

13

24

25000,00

105

Vicente Pantalla

35000,00

13

29

10000,00

105

Vicente Pantalla

35000,00

13

30

20000,00

106

Luis Antonio

27500,00

11

24

25000,00

106

Luis Antonio

27500,00

11

29

10000,00

106

Luis Antonio

27500,00

11

30

20000,00

107

Jorge Gutirrez

30000,00

22

24

25000,00

107

Jorge Gutirrez

30000,00

22

29

10000,00

107

Jorge Gutirrez

30000,00

22

30

20000,00

108

Ana Bustamante

35000,00

21

22

30000,00

108

Ana Bustamante

35000,00

21

24

25000,00

108

Ana Bustamante

35000,00

21

29

10000,00

Ing. Jos Rodrguez Mantilla

Pgina 8

Material de Clase SQL


108

Ana Bustamante

35000,00

21

30

20000,00

4.8. La Composicin externa LEFT, RIGHT y FULL OUTER JOIN


La composicin externa se escribe de manera similar al INNER JOIN indicando una condicin de
combinacin pero en el resultado se aaden filas que no cumplen la condicin de combinacin.
Sintaxis
FROM
<tabla_origen> {LEFT|RIGHT|FULL} [OUTER] JOIN <tabla_origen>
ON <condicion_combi>
La palabra OUTER es opcional y no aade ninguna funcin.
Las palabras LEFT, RIGHT y FULL indican la tabla de la cual se van a aadir las filas sin
correspondencia.
SELECT numemp,nombre,empleados.oficina, ciudad
FROM empleados LEFT JOIN oficinas
ON empleados.oficina=oficinas.oficina;
numemp

nombre

oficina

ciudad

101

Antonio Viguer

12

Alicante

102

Alvaro Jaumes

21

Badajoz

103

Juan Rovira

12

Alicante

104

Jos Gonzlez

12

Alicante

105

Vicente Pantalla

13

Castelln

106

Luis Antonio

11

Valencia

107

Jorge Gutirrez

22

A Corua

108

Ana Bustamante

21

Badajoz

109

Mara Sunta

11

Valencia

110

Juan Victor

NULL

NULL

Ahora s aparece el empleado 110 que no tiene oficina


Obtiene los empleados con su oficina y los empleados (tabla a la izquierda LEFT del JOIN) que no
tienen oficina aparecern tambin en el resultado con los campos de la tabla oficinas rellenados a
NULL.
SELECT numemp,nombre,empleados.oficina, ciudad, oficinas.oficina
FROM empleados RIGHT JOIN oficinas
ON empleados.oficina=oficinas.oficina;

Ing. Jos Rodrguez Mantilla

Pgina 9

Material de Clase SQL


numemp

nombre

oficina

ciudad

oficina

106

Luis Antonio

11

Valencia

11

109

Mara Sunta

11

Valencia

11

101

Antonio Viguer

12

Alicante

12

103

Juan Rovira

12

Alicante

12

104

Jos Gonzlez

12

Alicante

12

105

Vicente Pantalla

13

Castelln

13

102

Alvaro Jaumes

21

Badajoz

21

108

Ana Bustamante

21

Badajoz

21

107

Jorge Gutirrez

22

A Corua

22

NULL

NULL

NULL

Madrid

23

NULL

NULL

NULL

Aranjuez

24

NULL

NULL

NULL

Pamplona

26

NULL

NULL

NULL

Valencia

28

Las oficinas 23,24,26 y 28 no tienen empleados.


Obtiene los empleados con su oficina y las oficinas (tabla a la derecha RIGHT del JOIN) que no
tienen empleados aparecern tambin en el resultado con los campos de la tabla empleados
rellenados a NULL.
SELECT numemp,nombre,empleados.oficina, ciudad, oficinas.oficina
FROM empleados FULL JOIN oficinas
ON empleados.oficina=oficinas.oficina;
numemp

nombre

oficina

ciudad

oficina

101

Antonio Viguer

12

Alicante

12

102

Alvaro Jaumes

21

Badajoz

21

103

Juan Rovira

12

Alicante

12

104

Jos Gonzlez

12

Alicante

12

105

Vicente Pantalla

13

Castelln

13

106

Luis Antonio

11

Valencia

11

107

Jorge Gutirrez

22

A Corua

22

108

Ana Bustamante

21

Badajoz

21

109

Mara Sunta

11

Valencia

11

110

Juan Victor

NULL

NULL

NULL

NULL

NULL

NULL

Madrid

23

NULL

NULL

NULL

Aranjuez

24

NULL

NULL

NULL

Pamplona

26

NULL

NULL

NULL

Valencia

28

Aparecen tanto los empleados sin oficina como las oficinas sin empleados.
SELECT numemp,nombre,empleados.oficina, ciudad, oficinas.oficina

Ing. Jos Rodrguez Mantilla

Pgina 10

Material de Clase SQL


FROM empleados FULL OUTER JOIN oficinas
ON empleados.oficina=oficinas.oficina;
Es equivalente, la palabra OUTER como hemos dicho no aade ninguna funcionalidad y se utiliza si
se quiere por cuestiones de estilo.
NOTA: Cuando necesitamos obtener filas con datos de dos tablas con una condici n de
combinacin utilizaremos un JOIN, os aconsejo empezar por escribir el JOIN con la condicin que
sea necesaria para combinar las filas, y luego plantearos si la composicin debe de ser interna o
externa. Para este segundo paso sta sera la norma a seguir:
Empezamos con INNER JOIN.
Si pueden haber filas de la primera tabla que no estn relacionadas con filas de la segunda tabla y
nos interesa que salgan en el resultado, entonces cambiamos a LEFT JOIN.
Si pueden haber filas de la segunda tabla que no estn relacionadas con filas de la primera tabla y
nos interesa que salgan en el resultado, entonces cambiamos a RIGHT JOIN.
Si necesitamos LEFT y RIGHT entonces utilizamos FULL JOIN.
Siguiendo el ejemplo anterior nos preguntaramos:
Pueden haber empleados que no tengan oficina y nos interesan?, si es que s, necesitamos un
LEFT JOIN.
Seguiramos preguntando:
Pueden haber oficinas que no tengan empleados y nos interesan?, si es que s, necesitamos un
RIGHT JOIN.
Si al final necesitamos LEFT y tambin RIGHT entonces utilizamos FULL JOIN.
Para practicar puedes realizar este Ejercicio La composicin externa LEFT JOIN y RIGHT JOIN.
Nota: Para realizar los ejercicios, utiliza la base de datos GestionSimples.

Objetivo
Combinar datos de dos tablas que tienen algn dato en comn, con la finalidad de ampliar la
informacin en una nica tabla. Tendremos en cuenta los nulos, de forma que el LEFT o el RIGHT
indicarn qu tabla es la que deber aparecer, en caso de no tener correspondencia en la otra.

Ejercicio paso a paso


Listar todos los empleados y la ciudad y regin donde trabaja.
SELECT
numemp, nombre, edad, titulo, CONVERT(CHAR(8),contrato,3)AS contrato, jefe,
empleados.oficina,ciudad, region
FROM oficinas RIGHT JOIN empleados ON oficinas.oficina = empleados.oficina;
Resultado:

Ing. Jos Rodrguez Mantilla

Pgina 11

Material de Clase SQL


Numemp

Nombre

Edad

Titulo

Contrato

Jefe Oficina

Ciudad

Region

101

Antonio Viguer

45

representante

20/10/86

104

12

Alicante

este

102

Alvaro Jaumes

48

representante

10/12/86

108

21

Badajoz

oeste

103

Juan Rovira

29

representante

01/03/87

104

12

Alicante

este

104

Jos Gonzlez

33

dir ventas

19/05/87

106

12

Alicante

este

105

Vicente
Pantalla

37

representante

12/02/88

104

13

Castellon

este

106

Luis Antonio

52

director
general

14/06/88

NULL

11

Valencia

este

107

Jorge Gutirrez

49

representante

14/11/88

108

22

A Corua

oeste

108

Ana
Bustamante

62

dir ventas

12/10/89

106

21

Badajoz

oeste

109

Mara Sunta

31

representante

12/10/99

106

NULL

NULL

NULL

110

Juan Victor

41

representante

13/01/90

104

NULL

NULL

NULL

111

Juan Gris

50

representante

01/05/05

110

21

Badajoz

oeste

112

Julin
Martorell

50

representante

01/05/06

NULL

NULL

NULL

NULL

113

Juan Gris

18

representante

01/01/07

NULL

NULL

NULL

NULL

Listar todas las oficinas y los nombres y ttulos de sus directores.


SELECT oficinas.*, nombre AS director, titulo
FROM oficinas LEFT JOIN empleados ON dir = numemp;
Resultado:
Oficina

Ciudad

Region

Dir

Objetivo

Ventas

Director

Titulo

11

Valencia

este

106

57500,00

69300,00

Luis Antonio

director
general

12

Alicante

este

104

80000,00

73500,00

Jos Gonzlez

dir ventas

13

Castellon

este

105

35000,00

36800,00

Vicente

representante

Ing. Jos Rodrguez Mantilla

Pgina 12

Material de Clase SQL


Pantalla
21

Badajoz

oeste

108

72500,00

84400,00

Ana
Bustamante

dir ventas

22

A Corua

oeste

108

30000,00

18600,00

Ana
Bustamante

dir ventas

23

Madrid

centro

108

NULL

NULL

Ana
Bustamante

dir ventas

24

Aranjuez

centro

108

25000,00

15000,00

Ana
Bustamante

dir ventas

25

Valencia

NULL

NULL

NULL

NULL

NULL

NULL

26

Pamplona

norte

NULL

NULL

200000,00

NULL

NULL

27

Mstoles

Centro

NULL

NULL

0,00

NULL

NULL

28

Valencia

este

NULL

90000,00

0,00

NULL

NULL

29

Valencia

este

NULL

10000,00

2100,00

NULL

NULL

30

pamplona

norte

NULL

20000,00

NULL

NULL

NULL

31

Elx

NULL

NULL

NULL

0,00

NULL

NULL

Listar las oficinas con objetivo superior a 60.000 euros indicando para cada una el nombre de su
director.
SELECT oficinas.*, nombre AS director
FROM oficinas LEFT JOIN empleados ON dir = numemp
WHERE objetivo > 60000;
Resultado:
Oficina

Ciudad

Region

Dir

Objetivo

Ventas

Director

12

Alicante

este

104

80000,00

73500,00

Jos Gonzlez

21

Badajoz

oeste

108

72500,00

84400,00

Ana Bustamante

28

Valencia

este

NULL

90000,00

0,00

NULL

4.9. Combinar varias operaciones


Ing. Jos Rodrguez Mantilla

Pgina 13

Material de Clase SQL


En las operaciones anteriores tabla_origen puede ser a su vez una composicin de tablas, en este
caso aunque slo sea obligatorio cuando queramos cambiar el orden de ejecucin de las
composiciones, es recomendable utilizar parntesis para delimitar las composiciones.
Por ejemplo:
SELECT numemp, nombre, empleados.oficina, ciudad, oficinas.oficina, pedidos.*
FROM (oficinas RIGHT JOIN empleados
ON empleados.oficina = oficinas.oficina)
INNER JOIN pedidos on rep=numemp;
O bien:
SELECT numemp, nombre, empleados.oficina, ciudad, oficinas.oficina, pedidos.*
FROM oficinas RIGHT JOIN (empleados INNER JOIN pedidos on rep = numemp)
ON empleados.oficina = oficinas.oficina);

Ejercicios unidad 4: Consultas multitabla


Para realizar los ejercicios, debers utilizar la base de datos GestionSimples, en la carpeta Ejercicios
del curso tienes el PDF Tablas_Gestion para consultar en qu tablas est cada campo.

Ejercicio 1: La composicin de tablas


1.

Listar todos los pedidos, mostrando el precio y la descripcin del producto.


Resultado:
Codig Numpedi Fechapedid
o
do
o

Clie

Rep Fab Product Can Import Precio descripci


o
t
e
on

110036

1989-1012
00:00:00.0
00

210
7

11
0

aci

4100z

22,50

NUL
L

mont

110037

1989-1012
00:00:00.0
00

211
7

10
6

rei

2a44l

31,50

45,0
0

bomba l

112963

2008-0510
00:00:00.0
00

210
3

10
5

aci

41004

2
8

3,276

NUL
L

art t4

112968

1990-0111
00:00:00.0
00

210
2

10
1

aci

41004

3
4

39,78

NUL
L

art t4

112975

2008-0211

211
1

10
3

rei

2a44g

21,00

3,50

pas

Ing. Jos Rodrguez Mantilla

Pgina 14

Material de Clase SQL


00:00:00.0
00
6

112979

1989-1012
00:00:00.0
00

211
4

10
8

aci

4100z

150,0
0

NUL
L

mont

112983

2008-0510
00:00:00.0
00

210
3

10
5

aci

41004

7,02

NUL
L

art t4

112987

2008-0101
00:00:00.0
00

210
3

10
5

aci

4100y

1
1

275,0
0

NUL
L

extracto
r

112989

2008-1210
00:00:00.0
00

210
1

10
6

fea

114

14,58

2,43

cubo

10

112992

1990-0415
00:00:00.0
00

211
8

10
8

aci

41002

1
0

7,60

NUL
L

bisagra

11

112993

2008-0310
00:00:00.0
00

210
6

10
2

rei

2a45c

2
4

18,96

0,79

junta

12

112997

2008-0404
00:00:00.0
00

212
4

10
7

bic

41003

6,52

6,52

manivel
a

13

113003

2008-0205
00:00:00.0
00

210
8

10
9

im
m

779c

56,25

18,7
5

reostat
o3

14

113007

2008-0101
00:00:00.0
00

211
2

10
8

im
m

773c

29,25

9,75

reostat
o

15

113012

2008-0505
00:00:00.0
00

211
1

10
5

aci

41003

3
5

37,45

NUL
L

art t3

16

113013

2008-1228
00:00:00.0
00

211
8

10
8

bic

41003

6,52

6,52

manivel
a

17

113024

2008-0704
00:00:00.0
00

211
4

10
8

qsa

xk47

2
0

71,00

3,55

red

18

113027

2008-0205

210
3

10
5

aci

41002

5
4

450,0
0

NUL
L

bisagra

Ing. Jos Rodrguez Mantilla

Pgina 15

Material de Clase SQL


00:00:00.0
00
19

113034

2008-1105
00:00:00.0
00

210
7

11
0

rei

2a45c

6,32

0,79

junta

20

113042

2008-0101
00:00:00.0
00

211
3

10
1

rei

2a44r

225,0
0

45,0
0

bomba
r

21

113045

2008-0702
00:00:00.0
00

211
2

11
0

rei

2a44r

1
0

450,0
0

45,0
0

bomba
r

22

113048

2008-0202
00:00:00.0
00

212
0

10
2

im
m

779c

37,50

18,7
5

reostat
o3

23

113049

2008-0404
00:00:00.0
00

211
8

10
8

qsa

xk47

7,76

3,55

red

24

113051

2008-0706
00:00:00.0
00

211
8

10
8

qsa

xk47

14,20

3,55

red

25

113055

2009-0401
00:00:00.0
00

210
8

10
1

aci

4100x

1,50

NUL
L

junta

26

113057

2008-1101
00:00:00.0
00

211
1

10
3

aci

4100x

2
4

NULL

NUL
L

junta

27

113058

1989-0704
00:00:00.0
00

210
8

10
9

fea

112

1
0

14,80

1,48

cubo

28

113062

2008-0704
00:00:00.0
00

212
4

10
7

bic

41003

1
0

24,30

6,52

manivel
a

29

113065

2008-0603
00:00:00.0
00

210
6

10
2

qsa

xk47

21,30

3,55

red

30

113069

2008-0801
00:00:00.0
00

210
9

10
7

im
m

773c

2
2

313,5
0

9,75

reostat
o

Ing. Jos Rodrguez Mantilla

Pgina 16

Material de Clase SQL


2.

Listar los pedidos superiores a 250 euros, incluyendo el nombre del vendedor que tom el
pedido y el nombre del cliente que lo solicit.
Resultado:
Numpedid Fechapedid
o
o

3.

Clie

Rep

Fab

Product Can Precio


o
t

Cliente vendedor

112987

01/01/08

210
3

10
5

aci

4100y

11

275,0
0

Jaime
Lloren
s

Vicente
Pantalla

113027

05/02/08

210
3

10
5

aci

41002

54

450,0
0

Jaime
Lloren
s

Vicente
Pantalla

113045

02/07/08

211
2

11
0

rei

2a44r

10

450,0
0

Mara
Silva

Juan
Victor

113069

01/08/08

210
9

10
7

im
m

773c

22

313,5
0

Albert
o
Juanes

Jorge
Gutirre
z

Listar los pedidos superiores a 250 euros, mostrando el nombre del cliente que solicit el
pedido y el nombre del vendedor asignado a ese cliente.
Resultado:
Codig Numpedi Fechapedid Clie Rep Fab Produc Can Import Cliente Vendedor
o
do
o
to
t
e
asignado

4.

112987

2008-0101
00:00:00.
000

210
3

10
5

aci

4100
y

1
1

275,
00

Jaime
Llore
ns

Juan
Victor

18

113027

2008-0205
00:00:00.
000

210
3

10
5

aci

4100
2

5
4

450,
00

Jaime
Llore
ns

Juan
Victor

21

113045

2008-0702
00:00:00.
000

211
2

11
0

rei

2a44r

1
0

450,
00

Mara
Silva

Ana
Bustama
nte

30

113069

2008-0801
00:00:00.
000

210
9

10
7

im
m

773c

2
2

313,
50

Alber
to
Juane
s

Juan
Rovira

Listar los pedidos superiores a 250 euros, mostrando adems el nombre del cliente que
solicit el pedido y el nombre del vendedor asignado a ese cliente y la ciudad de la oficina
donde el vendedor trabaja.
Resultado:
Numpedido

Clie

Rep

Cliente

Repclie Vendedor asignado

ciudad

112987

2103

105

Jaime Llorens

105

Juan Victor

NULL

113027

2103

105

Jaime Llorens

105

Juan Victor

NULL

Ing. Jos Rodrguez Mantilla

Pgina 17

Material de Clase SQL

5.

113045

2112

110

Mara Silva

110

Ana Bustamante

Badajoz

113069

2109

107

Alberto Juanes

107

Juan Rovira

Alicante

Hallar los pedidos recibidos los das en que un nuevo empleado fue contratado.
Resultado:
Numpedido

6.

Fechapedido

Rep Numemp

Nombre

Contrato

110036

1989-10-12
00:00:00.000

110

108

Ana
Bustamante

1989-10-12
00:00:00.000

110037

1989-10-12
00:00:00.000

106

108

Ana
Bustamante

1989-10-12
00:00:00.000

112979

1989-10-12
00:00:00.000

108

108

Ana
Bustamante

1989-10-12
00:00:00.000

Hallar los empleados que realizaron su primer pedido el mismo da que fueron contratados.
Resultado:
Numemp
108

7.

Nombre
Ana
Bustamante

Contrato
1989-10-12
00:00:00.000

Numpedido Rep
112979

108

fechapedido
1989-10-12
00:00:00.000

Mostrar de cada empleado su cdigo, nombre, ventas, oficina y ciudad en la que est
ubicada su oficina.
Resultado:
Numemp

8.

Nombre

ventas

Oficina

ciudad

101

Antonio Viguer

30500,00

12

Alicante

102

Alvaro Jaumes

47400,00

21

Badajoz

103

Juan Rovira

28600,00

12

Alicante

104

Jos Gonzlez

14300,00

12

Alicante

105

Vicente Pantalla

36800,00

13

Castellon

106

Luis Antonio

29900,00

11

Valencia

107

Jorge Gutirrez

18600,00

22

A Corua

108

Ana Bustamante

36100,00

21

Badajoz

109

Mara Sunta

39200,00

NULL

NULL

110

Juan Victor

7600,00

NULL

NULL

111

Juan Gris

60000,00

NULL

NULL

112

Julin Martorell

91000,00

NULL

NULL

113

Juan Gris

0,00

NULL

NULL

Listar los empleados con una cuota superior a la de su jefe, los campos a obtener son el
nmero, nombre y cuota del empleado y nmero, nombre y cuota de su jefe.
Resultado:
Numemp

Nombre

Ing. Jos Rodrguez Mantilla

Cuota

Jefe

Nombre jefe

Cuota jefe

Pgina 18

Material de Clase SQL

9.

101

Antonio Viguer

30000,00

104

Jos Gonzlez

20000,00

103

Juan Rovira

27500,00

104

Jos Gonzlez

20000,00

105

Vicente Pantalla

35000,00

104

Jos Gonzlez

20000,00

108

Ana Bustamante

35000,00

106

Luis Antonio

27500,00

Desde el entorno grfico cambia el empleado 111, asgnale el jefe 110 y la oficina 21.
Despus cambia la sentencia anterior para que salgan tambin los empleados cuyo jefe no
tenga cuota.
Resultado:
Numemp

Nombre

Cuota

Jefe

Nombre jefe

Cuota jefe

101

Antonio Viguer

30000,00

104

Jos Gonzlez

20000,00

103

Juan Rovira

27500,00

104

Jos Gonzlez

20000,00

105

Vicente Pantalla

35000,00

104

Jos Gonzlez

20000,00

108

Ana Bustamante

35000,00

106

Luis Antonio

27500,00

111

Juan Gris

10000,00

110

Juan Victor

NULL

10. Listar los empleados que no estn asignados a la misma oficina que su jefe, queremos
nmero, nombre y nmero de oficina tanto del empleado como de su jefe.
Resultado:
Numemp

Nombre

Oficina Jefe

Nombre jefe

Oficina jefe

104

Jos Gonzlez

12

106

Luis Antonio

11

105

Vicente Pantalla

13

104

Jos Gonzlez

12

107

Jorge Gutirrez

22

108

Ana Bustamante

21

108

Ana Bustamante

21

106

Luis Antonio

11

11. En el punto anterior no salen los que no tienen oficina, cambiar la sentencia para que
aparezcan.
Resultado:
Numemp

Nombre

Oficina Jefe

Nombre jefe

Oficina jefe

104

Jos Gonzlez

12

106

Luis Antonio

11

105

Vicente Pantalla

13

104

Jos Gonzlez

12

107

Jorge Gutirrez

22

108

Ana Bustamante

21

108

Ana Bustamante

21

106

Luis Antonio

11

109

Mara Sunta

NULL

106

Luis Antonio

11

110

Juan Victor

NULL

104

Jos Gonzlez

12

111

Juan Gris

21

110

Juan Victor

NULL

12. Lo mismo que la anterior pero queremos que aparezca tambin la ciudad de las oficinas
(tanto del empleado como de su jefe).
Resultado:

Ing. Jos Rodrguez Mantilla

Pgina 19

Material de Clase SQL


Numemp

Nombre

Oficina

Ciudad

Jefe

Nombre jefe

Oficina
jefe

ciudad

104

Jos Gonzlez

12

Alicante

106

Luis Antonio

11

Valencia

105

Vicente
Pantalla

13

Castellon

104

Jos Gonzlez

12

Alicante

107

Jorge
Gutirrez

22

A Corua

108

Ana
Bustamante

21

Badajoz

108

Ana
Bustamante

21

Badajoz

106

Luis Antonio

11

Valencia

109

Mara Sunta

NULL

NULL

106

Luis Antonio

11

Valencia

110

Juan Victor

NULL

NULL

104

Jos Gonzlez

12

Alicante

111

Juan Gris

21

Badajoz

110

Juan Victor

NULL

NULL

Ejercicio 2: Composicin de Tablas


1.

Listar todos los pedidos, mostrando el precio y la descripcin del producto.


SELECT pedidos.*, precio, descripcion
FROM pedidos INNER JOIN productos ON fab = idfab AND producto = idproducto;

2.

Listar los pedidos superiores a 250 euros, incluyendo el nombre del vendedor que tom el
pedido y el nombre del cliente que lo solicit.
SELECT numpedido, CONVERT(CHAR(8),fechapedido,3) AS fechapedido, clie, rep, fab,
producto, cant, importe, clientes.nombre AS cliente, empleados.nombre AS vendedor
FROM (pedidos INNER JOIN empleados ON rep = numemp)
INNER JOIN clientes ON clie = numclie
WHERE importe > 250;

3.

Listar los pedidos superiores a 250 euros, mostrando el nombre del cliente que solicit el
pedido y el nombre del vendedor asignado a ese cliente.
SELECT pedidos.*, clientes.nombre AS cliente, empleados.nombre AS [vendedor
asignado]
FROM (pedidos INNER JOIN clientes ON clie = numclie)
INNER JOIN empleados ON repclie = numemp
WHERE importe > 250;

4.

Listar los pedidos superiores a 250 euros, mostrando adems el nombre del cliente que
solicit el pedido y el nombre del vendedor asignado a ese cliente y la ciudad de la oficina
donde el vendedor trabaja.

Ing. Jos Rodrguez Mantilla

Pgina 20

Material de Clase SQL


SELECT numpedido, clie, rep, clientes.nombre AS cliente, repclie, empleados.nombre
AS vendedor, ciudad
FROM ((pedidos INNER JOIN clientes ON clie = numclie)
INNER JOIN empleados ON repclie = numemp)
LEFT JOIN oficinas ON empleados.oficina=oficinas.oficina
WHERE importe > 250;

5.

Hallar los pedidos recibidos los das en que un nuevo empleado fue contratado.
SELECT numpedido, fechapedido, rep, numemp, nombre, contrato
FROM pedidos, empleados
WHERE fechapedido=contrato;

6.

Hallar los empleados que realizaron su primer pedido el mismo da que fueron contratados.
SELECT numemp, nombre, contrato, numpedido, rep, fechapedido
FROM pedidos INNER JOIN empleados ON rep = numemp
WHERE fechapedido = contrato;

7.

Mostrar de cada empleado su cdigo, nombre, ventas, oficina y ciudad en la que est
ubicada su oficina.
SELECT numemp, nombre,empleados.ventas,empleados.oficina,ciudad
FROM empleados LEFT JOIN oficinas ON empleados.oficina=oficinas.oficina;

8.

Listar los empleados con una cuota superior a la de su jefe, los campos a obtener son el
nmero, nombre y cuota del empleado y nmero, nombre y cuota de su jefe.
SELECT empleados.numemp, empleados.nombre, empleados.cuota, empleados.jefe,
jefes.nombre AS [Nombre jefe], jefes.cuota AS [Cuota jefe]
FROM empleados LEFT JOIN empleados jefes ON empleados.jefe = jefes.numemp;

9.

Desde el entorno grfico cambia el empleado 111, asgnale el jefe 110 y la oficina 21.
Despus cambia la sentencia anterior para que salgan tambin los empleados cuyo jefe no
tenga cuota.
SELECT empleados.numemp, empleados.nombre, empleados.cuota, empleados.jefe,
jefes.nombre, jefes.cuota
FROM empleados INNER JOIN empleados jefes ON empleados.jefe = jefes.numemp
WHERE empleados.cuota > jefes.cuota OR
(empleados.cuota IS NOT NULL AND jefes.cuota IS NULL)

Ing. Jos Rodrguez Mantilla

Pgina 21

Material de Clase SQL


10. Listar los empleados que no estn asignados a la misma oficina que su jefe, queremos
nmero, nombre y nmero de oficina tanto del empleado como de su jefe.
SELECT e.numemp, e.nombre, e.oficina, e.jefe, j.nombre as [nombre jefe], j.oficina AS
[oficina jefe]
FROM empleados e INNER JOIN empleados j ON e.jefe = j.numemp
WHERE e.oficina <> j.oficina;

11. En el punto anterior no salen los que no tienen oficina, cambiar la sentencia para que
aparezcan.
SELECT e.numemp, e.nombre, e.oficina, e.jefe, j.nombre as [nombre jefe], j.oficina AS
[oficina jefe]
FROM empleados e INNER JOIN empleados j ON e.jefe = j.numemp
WHERE e.oficina <> j.oficina OR e.oficina IS NULL OR j.oficina IS NULL;

12. Lo mismo que la anterior pero queremos que aparezca tambin la ciudad de las oficinas
(tanto del empleado como de su jefe).
SELECT e.numemp, e.nombre, e.oficina, ofiemp.ciudad, e.jefe, j.nombre as [nombre
jefe], j.oficina AS [oficina jefe], ofijefe.ciudad
FROM (oficinas ofiemp RIGHT JOIN empleados e ON ofiemp.oficina= e.oficina)
INNER JOIN (empleados j LEFT JOIN oficinas ofijefe ON j.oficina = ofijefe.oficina)
ON e.jefe = j.numemp
WHERE e.oficina <> j.oficina OR e.oficina IS NULL OR j.oficina IS NULL;

Ejercicio 2: Comparar tablas


1.

Obtener los empleados de GestionSimples que aparecen en GestionA con otra oficina.
SELECT numemp, oficina
FROM gestionsimples.dbo.empleados
EXCEPT
SELECT numemp, oficina
FROM gestionA.dbo.empleados;

Unidad 5. Consultas de resumen (I)


5.1. Introduccin
Una de las funcionalidades de la sentencia SELECT es el permitir obtener resmenes de los datos
contenidos en las columnas de las tablas.

Ing. Jos Rodrguez Mantilla

Pgina 22

Material de Clase SQL


Para poder llevarlo a cabo la sentencia SELECT consta de una serie de clusulas especficas (GROUP
BY, HAVING), y Transact-SQL tiene definidas unas funciones para poder realizar estos clculos, las
funciones de agregado (tambin llamadas funciones de columna).
La diferencia entre una consulta de resumen y una consulta de las que hemos visto hasta ahora es
que en las consultas normales las filas del resultado se obtienen directamente de las filas del
origen de datos y cada dato que aparece en el resultado tiene su dato correspondiente en el
origen de la consulta mientras que las filas generadas por las consultas de resumen no representan
datos del origen sino un total calculado sobre estos datos. Esta diferencia har que las consultas de
resumen tengan algunas limitaciones que veremos a lo largo del tema.
Un ejemplo sera:

A la izquierda tenemos una consulta simple que nos saca las oficinas con sus ventas ordenadas
por regin, y a la derecha una consulta de resumen que obtiene la suma de las ventas de las
oficinas de cada regin

5.2. Las funciones de agregado


Una funcin de agregado SQL acepta un grupo de datos (normalmente una columna de datos)
como argumento, y produce un nico dato que resume el grupo. Por ejemplo la funcin AVG()
acepta una columna de datos numricos y devuelve la media aritmtica (average) de los valore s
contenidos en la columna.
El hecho de utilizar una funcin de agregado en una consulta, convierte sta en una consulta de
resumen.
Todas las funciones de agregado tienen una estructura muy parecida:
Funcin ([ALL|DISTINCT] expression)

El grupo de valores sobre el que acta la funcin lo determina el resultado de la expresin que ser
un nombre de columna o una expresin basada en una columna o varias del origen de datos. En la
expresin nunca puede aparecer una funcin de agregado ni una subconsulta.
La palabra ALL indica que se tiene que tomar en cuenta todos los valores de la columna. Es el valor
por defecto.

Ing. Jos Rodrguez Mantilla

Pgina 23

Material de Clase SQL


La palabra DISTINCT hace que se consideren todas las repeticiones del mismo valor como uno slo
(considera valores distintos).
Todas las funciones de agregado se aplican a las filas del origen de datos una vez ejecutada la
clusula WHERE (si la hubiera).
Si exceptuamos la funcin COUNT, todas las funciones de agregado ignoran los valores NULL.
Una funcin de agregado puede aparecer en la lista de seleccin en cualquier lugar en el que
puede aparecer un nombre de columna. Puede, por ejemplo, formar parte de una expresin pero
no se pueden anidar funciones de agregado.
Tampoco se pueden mezclar funciones de columna con nombres de columna ordina rios. Hay
excepciones a esta regla pero cuando definimos agrupaciones y subconsultas que veremos ms
adelante.

5.3. La funcin COUNT


COUNT ({[ALL|DISTINCT] expresion | * } )
Expresion puede ser de cualquier tipo excepto text, image o ntext. No se permite utilizar funciones
de agregado ni subconsultas. El tipo de dato devuelto es intSi el nmero de valores devueltos por
expresion es superior a 231-1, COUNT genera un error, en ese caso hay que utilizar la funcin
COUNT_BIG.
La funcin cuenta los valores distintos de NULL que hay en la columna. La palabra ALL indica que se
tienen que tomar todos los valores de la columna, mientras que DISTINCT hace que se consideren
todas las repeticiones del mismo valor como uno solo. Estos parmetros son opcionales, por
defecto se considera ALL.
Por ejemplo:
SELECT COUNT(region) FROM oficinas;
Devuelve 9 porque tenemos nueve valores no nulos en la columna region. A la hora de interpretar
un COUNT es conveniente no olvidar que cuenta valores no nulos, por ejemplo si interpretramos
la sentencia tal cual se lee, cuntas regiones tenemos en oficinas sera errneo, realmente
estamos obteniendo cuntas oficinas tienen una regin asignada.
SELECT COUNT(DISTINCT region) FROM oficinas;
Devuelve 4 porque tenemos cuatro valores distintos, no nulos, en la columna regin, los valores
repetidos los considera slo una vez. Ahora s nos devuelve cuntas regiones tenemos en oficinas.
Si utilizamos * en vez de expresin, devuelve el nmero de filas del origen que nos qued an
despus de ejecutar la clusula WHERE.
COUNT(*) no acepta parmetros y no se puede utilizar con DISTINCT. COUNT( *) no requiere un
parmetro expression porque, por definicin, no utiliza informacin sobre ninguna columna
especfica. En el recuento se incluyen las filas que contienen valores NULL.
SELECT COUNT(*) FROM empleados WHERE oficina=12;

Ing. Jos Rodrguez Mantilla

Pgina 24

Material de Clase SQL


Obtiene el nmero de empleados asignados a la oficina 12.
Si tenemos un COUNT(columna) y columna no contiene valores nulos, se obtiene el mismo
resultado que COUNT(*) pero el COUNT(*) es ms rpido por lo que en este caso hay que utilizarlo
en vez de COUNT(columna).
Por ejemplo:
SELECT COUNT(*) FROM empleados WHERE oficina IS NOT NULL;
Es mejor que:
SELECT COUNT(oficina) FROM empleados WHERE oficina IS NOT NULL;
Las dos nos devuelven el nmero de empleados que tienen una oficina asignada pero la primera es
mejor porque se calcula ms rpidamente.
Para practicar puedes realizar este Ejercicio La funcin COUNT.
Nota: Para realizar los ejercicios, utiliza la base de datos GestionSimples.

Objetivo
Realizar consultas de resumen utilizando funciones de agregado. En este caso COUNT.

Ejercicio paso a paso


Cuntas oficinas tienen empleados?
SELECT COUNT(DISTINCT oficina) AS [Oficinas con empleados]
FROM empleados;
Si no incluimos DISTINCT obtenemos el n de valores no nulos que tenemos en la columna oficina
es decir n de empleados asignados a una oficina.
Resultado:
Oficinas con empleados
5

Cuntos empleados superan su cuota (tienen supervit positivo)?


SELECT count(*) AS [Empleados buenos]
FROM empleados
WHERE ventas > cuota;

Ing. Jos Rodrguez Mantilla

Pgina 25

Material de Clase SQL


Resultado:
Empleados buenos
9

Cuntas oficinas tienen empleados que superan su cuota (tienen supervit positivo)?
SELECT count(DISTINCT oficina) AS [Oficinas buenas]
FROM empleados
WHERE ventas > cuota ;
Resultado:
Oficinas buenas
|4

Cuntas oficinas tienen empleados cuyas ventas superan el objetivo de su oficina?


SELECT COUNT(DISTINCT empleados.oficina) AS Cuntas
FROM empleados INNER JOIN oficinas ON empleados.oficina = oficinas.oficina
WHERE empleados.ventas > objetivo;
Resultado:
Cuntas
1

5.4. La funcin COUNT_BIG


Funciona igual que la funcin COUNT. La nica diferencia entre ambas funciones est en los
valores devueltos, COUNT_BIG siempre devuelve un valor de tipo bigint y por lo tanto admite ms
valores de entrada, no est limitado a 231-1 valores de entrada como COUNT.

5.5. La funcin MAX


MAX ([ALL|DISTINCT] expression)
Devuelve el valor mximo de la expresin sin considerar los nulos.MAX se puede usar con
columnas numricas, de caracteres y de datetime, pero no con columnas de bit. No se permiten
funciones de agregado ni subconsultas.Utilizar DISTINCT no tiene ningn sentido con MAX (el valor
mximo ser el mismo si consideramos las repeticiones o no) y slo se incluye para la
compatibilidad con SQL-92.Por ejemplo:

Ing. Jos Rodrguez Mantilla

Pgina 26

Material de Clase SQL


SELECT SUM(ventas) AS VentasTotales, MAX(objet ivo) AS MayorObjetivo
FROM oficinas;
Para practicar puedes realizar este Ejercicio La funcin MAX.
Nota: Para realizar los ejercicios, utiliza la base de datos GestionSimples.

Objetivo
Realizar consultas de resumen utilizando funciones de agregado. En este caso MAX.

Ejercicio paso a paso


Hallar el mejor supervit de todos los empleados.
SELECT MAX(ventas - cuota) AS [Mejor superavit]
FROM empleados;
Resultado:
Mejor supervit
81000,00

5.6. La funcin MIN


MIN ([ALL|DISTINCT] expression)
Devuelve el valor mnimo de la expresin sin considerar los nulos.MIN se puede usar con columnas
numricas, de caracteres y de datetime, pero no con columnas de bit. No se permiten funciones
de agregado ni subconsultas.Utilizar DISTINCT no tiene ningn sentido con MIN (el valor mnimo
ser el mismo si consideramos las repeticiones o no) y slo se incluye para la compatibilidad con
SQL-92.

5.7. La funcin SUM


SUM ([ALL|DISTINCT] expresion )
Devuelve la suma de los valores devueltos por la expresin.Slo puede utilizarse con columnas
numricas.El resultado ser del mismo tipo aunque puede tener una precisin mayor.
SELECT SUM(importe) FROM pedidos;
Obtiene el importe total vendido en todos los pedidos.

Ing. Jos Rodrguez Mantilla

Pgina 27

Material de Clase SQL


SELECT SUM(ventas) AS VentasTotales, MAX(objet ivo) AS MayorObjetivo
FROM oficinas;
Devuelve la suma de las ventas de todas las oficinas y de los objetivos de todas las oficinas, el de
mayor importe.
Para practicar puedes realizar este Ejercicio La funcin SUM.
Nota: Para realizar los ejercicios, utiliza la base de datos GestionSimples.

Objetivo
Realizar consultas de resumen utilizando funciones de agregado. En este caso SUM.

Ejercicio paso a paso


Cul es el total de cuotas y total de ventas de todos los empleados?
SELECT SUM(cuota) AS [Total cuotas], SUM(ventas) AS [Total ventas]
FROM empleados;
Resultado:
Total cuotas Total ventas
273000,00

440000,00

Cul es el importe total de los pedidos realizados por el empleado Luis Antonio?
SELECT SUM(importe) AS [Importe vendido]
FROM pedidos INNER JOIN empleados ON rep = numemp
WHERE nombre = 'Luis Antonio';
Resultado:
Importe vendido
46,08

5.9. La funcin VAR


VAR ([ALL|DISTINCT] expresion )
Devuelve la varianza estadstica de todos los valores de la expresin especificada.

Ing. Jos Rodrguez Mantilla

Pgina 28

Material de Clase SQL


VAR slo se puede utilizar con columnas numricas. Los valores NULL se pasan por alto.

5.10. La funcin VARP


VARP ([ALL|DISTINCT] expresion )
Devuelve la varianza estadstica de la poblacin para todos los valores de la expresin especificada.
Slo se puede utilizar con columnas numricas. Los valores NULL se pasan por alto.

5.11. La funcin STDEV


STDEV ([ALL|DISTINCT] expresion )
Devuelve la desviacin tpica estadstica de todos los valores de la expresin especificada.
Slo se puede utilizar con columnas numricas. Los valores NULL se pasan por alto.

5.12. La funcin STDEVP


STDEVP ([ALL|DISTINCT] expresion )
Devuelve la desviacin estadstica estndar para la poblacin de todos los valores de la expresin
especificada.
Slo se puede utilizar con columnas numricas. Los valores NULL se pasan por alto.

5.13. La funcin GROUPING


GROUPING (nb_columna)
Es una funcin de agregado que genera como salida una columna adicional con el valor 1 si la fila
se agrega mediante el operador CUBE o ROLLUP, o el valor 0 cuando la fila no es el resultado de
CUBE o ROLLUP.
Nb_columna tiene que ser una de las columnas de agrupacin y la clusula GROUP BY debe
contener el operador CUBE o ROLLUP.
En el siguiente punto, cuando veamos las clusulas CUBE y ROLLUP quedar ms claro.

5.14. Agrupamiento de filas (clusula GROUP BY).


Hasta ahora las consultas sumarias que hemos visto obtienen totales de todas las filas del origen y
producen una nica fila de resultado.

Ing. Jos Rodrguez Mantilla

Pgina 29

Material de Clase SQL


Muchas veces cuando calculamos resmenes nos interesan totales parciales, por ejemplo saber de
cada empleado cunto ha vendido, y cul ha sido su pedido mximo, de cada cliente cundo fue la
ltima vez que nos compr, etc.
En todos estos casos en vez de obtener una fila nica de resultados necesitamos una fila por cada
empleado, cliente, etc.
Podemos obtener estos subtotales con la clusula GROUP BY.
GROUP BY [ ALL ] expresion_agrupacion [ ,...n ]
[ WITH { CUBE | ROLLUP } ]
Una consulta con una clusula GROUP BY agrupa los datos de la tabla origen y produce una nica
fila resultado por cada grupo formado. Las columnas indicadas en el GROUP BY se llaman
columnas de agrupacin o agrupamiento .
Cuando queremos realizar una agrupacin mltiple, por varias columnas, stas se indican en la
clusula GROUP BY en el orden de mayor a menor agrupacin igual que con la clusula ORDER BY.
expresion_agrupacion puede ser una columna o una expresin no agregada que haga referencia a
una columna devuelta por la clusula FROM. Un alias de columna que est definido en la lista de
seleccin no puede utilizarse para especificar una columna de agrupamiento.
No se pueden utilizar columnas de tipo text, ntext e image en expresion_agrupacion.
En las clusulas GROUP BY que no contengan CUBE o ROLLUP, el nmero de columnas de
agrupacin est limitado por los tamaos de columna de GROUP BY, las columnas de agregado y
los valores de agregado que participan en la consulta. Este lmite procede del lmite de 8.060 bytes
de la tabla de trabajo intermedia que se necesita para contener los resultados intermedios de la
consulta. Se permite un mximo de 10 expresiones de agrupamiento cuando se especifica CUBE o
ROLLUP.
Si en la columna de agrupacin existen valores nulos, se generar una fila de resumen para este
valor, en este caso se considera el valor nulo como otro valor cualquiera.
Ejemplo:
SELECT oficina, count(numemp) AS [Nmero de empleados]
FROM empleados
GROUP BY oficina;
Resultado:
oficina Nmero de empleados
NULL

11

12

Ing. Jos Rodrguez Mantilla

Pgina 30

Material de Clase SQL


13

21

22

Hay empleados sin oficinas (con oficina a nulo), estos forman un grupo con el valor NULL en
oficina, en este caso hay dos empleados as.
Podemos indicar varias columnas de agrupacin.
Ejemplo:
SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo]
FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY rep, clie
ORDER BY rep, clie;
Resultado:
rep

clie

Nmero Importe
de pedidos mximo

101

2113

225,00

102

2106

21,30

102

2120

37,50

103

2111

21,00

105

2103

275,00

105

2111

37,45

106

2101

14,58

107

2109

313,50

107

2124

24,30

108

2112

29,25

108

2114

71,00

Ing. Jos Rodrguez Mantilla

Pgina 31

Material de Clase SQL


108

2118

14,20

De cada representante obtenemos el nmero de pedidos y el importe mximo vendido a cada


cliente, de las ventas de 1997. La clusula ORDER BY se ha incluido para que las filas aparezcan
ordenadas y quede ms claro.
Hemos dicho que los resmenes se calculan sobre todas las filas del origen despus de haber
ejecutado el WHERE, pues ALL permite obtener un resumen de las filas que no cumplen el WHERE.
ALL Incluye todos los grupos y conjuntos de resultados, incluso aquellos en los que no hay filas que
cumplan la condicin de bsqueda especificada en la clusula WHERE. Cuando se especifica ALL, se
devuelven valores NULL para las columnas de resumen de los grupos que no cumplen la condicin
de bsqueda. No se puede especificar ALL con los operadores CUBE y ROLLUP.
GROUP BY ALL no se admite en consultas que tienen acceso a tablas remotas si tambin hay una
clusula WHERE en la consulta.
Por ejemplo, vamos a modificar la consulta anterior:
SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo]
FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY ALL rep, clie
ORDER BY rep, clie;
Resultado:
rep

clie

Nmero Importe
de pedidos mximo

101

2102

NULL

101

2108

NULL

101

2113

225,00

102

2106

21,30

102

2120

37,50

103

2111

21,00

105

2103

275,00

105

2111

37,45

106

2101

14,58

106

2117

NULL

107

2109

313,50

107

2124

24,30

108

2112

29,25

108

2114

71,00

108

2118

14,20

Cul ha sido el efecto de aadir ALL? Se han aadido filas para las filas del origen que no cumplen
la condicin del WHERE pero sin que intervengan en el clculo de las funciones de agregado.

Ing. Jos Rodrguez Mantilla

Pgina 32

Material de Clase SQL


Por ejemplo el representante 101 tiene pedidos con el cliente 2102 pero estos pedidos no son del
ao 1997, por eso aparece la primera fila (no estaba en el resultado de la otra consulta) pero con 0
y NULL como resultados de las funciones de agregado.
ROLLUP especifica que, adems de las filas que normalmente proporciona GROUP BY, se incluyen
filas de resumen en el conjunto de resultados. Los grupos se resumen en un orden jerrquico,
desde el nivel inferior del grupo hasta el superior. La jerarqua del grupo se determina por el orden
en que se especifican las columnas de agrupamiento. Cambiar el orden de las columnas de
agrupamiento puede afectar al nmero de filas generadas en el conjunto de resultados.
Por ejemplo:
SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo]
FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY rep, clie WITH ROLLUP;
Resultado:
rep

clie

Nmero Importe
de pedidos mximo

101

2113

225,00

101

NULL

225,00

102

2106

21,30

102

2120

37,50

102

NULL

37,50

103

2111

21,00

103

NULL

21,00

105

2103

275,00

105

2111

37,45

105

NULL

275,00

106

2101

14,28

106

NULL

14,28

107

2109

313,50

107

2124

24,30

107

NULL

313,50

108

2112

29,25

108

2114

71,00

108

2118

14,20

108

NULL

71,00

...

...

...

...

NULL

NULL

23

450,00

Efecto: Se han aadido automticamente subtotales por cada nivel de agrupamiento y una lnea de
totales generales al final. En este caso no hemos incluido ORDER BY porque las filas salen ya
ordenadas.

Ing. Jos Rodrguez Mantilla

Pgina 33

Material de Clase SQL


CUBE especifica que, adems de las filas que normalmente proporciona GROUP BY, deben incluirse
filas de resumen en el conjunto de resultados. Se devuelve una fila de resumen GROUP BY por
cada posible combinacin de grupo y subgrupo del conjunto de resultados. En el resultado se
muestra una fila de resumen GROUP BY como NULL, pero se utiliza para indicar todos los valores.
Por ejemplo:
SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo]
FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY rep, clie WITH CUBE;
Resultado:
rep

clie

Nmero Importe
de pedidos mximo

101

2113

225,00

101

NULL

225,00

102

2106

21,30

102

2120

37,50

102

NULL

37,50

103

2111

21,00

103

NULL

21,00

105

2103

275,00

105

2111

37,45

105

NULL

275,00

106

2101

14,28

106

NULL

14,28

107

2109

313,50

107

2124

24,30

107

NULL

313,50

108

2112

29,25

108

2114

71,00

108

2118

14,20

108

NULL

71,00

...

...

...

...

NULL

NULL

23

450,00

NULL

2101

14,58

NULL

2103

275,00

NULL

2106

21,30

NULL

2107

6,32

NULL

2108

56,25

NULL

2109

313,50

NULL

2111

37,45

Ing. Jos Rodrguez Mantilla

Pgina 34

Material de Clase SQL


NULL

2112

450,00

NULL

2113

225,00

NULL

2114

71,00

NULL

2118

14,20

NULL

2120

37,50

NULL

2124

24,30

Efecto: Obtenemos adems de los resultados obtenidos con ROLLUP (los totales por cada
representante), los totales por el otro criterio (los totales por cada cliente).
El nmero de filas de resumen del conjunto de resultados se determina mediante el nmero de
columnas que contiene la clusula GROUP BY. Cada operando (columna) de la clusula GROUP BY
se enlaza segn el agrupamiento NULL y se aplica el agrupamiento al resto de los operandos
(columnas). CUBE devuelve todas las combinaciones posibles de grupo y subgrupo.
Tanto si utilizamos CUBE como ROLLUP, nos ser til la funcin de agregado GROUPING.
Si cogemos por ejemplo la primera fila remarcada (101 NULL ) el valor NULL, no sabemos si se
refiere a una fila de subtotal o a que el representante 101 ha realizado un pedido sin nmero de
cliente. Para poder salvar este problema se utiliza la funcin de agregado GROUPING.
SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe) AS [Importe mximo],
GROUPING(clie) AS [Fila resumen]
FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY rep, clie WITH ROLLUP;

rep

clie

Nmero Importe
Fila
de pedidos mximo Resumen

101

2113

225,00

101

NULL

225,00

102

2106

21,30

102

2120

37,50

102

NULL

37,50

103

2111

21,00

Las filas que corresponden a subtotales aparecen con un 1 y las normales con un cero.
Ahora que estamos ms familiarizados con las columnas de agrupamiento debemos comentar una
regla a no olvidar:
EN LA LISTA DE SELECCIN DE UNA CONSULTA DE RESUMEN UN NOMBRE DE COLUMNA NO
PUEDE APARECER FUERA DE UNA FUNCIN DE AGREGADO SI NO ES UNA COLUMNA DE
AGRUPACIN.
Para practicar puedes realizar este Ejercicio Agrupar filas con GROUP BY.
Nota: Para realizar los ejercicios, utiliza la base de datos GestionSimples.

Objetivo
Ing. Jos Rodrguez Mantilla

Pgina 35

Material de Clase SQL


Realizar consultas de resumen utilizando la clusula GROUP BY para agrupar filas.

Ejercicio paso a paso


Hallar el importe medio de pedidos realizados por cada empleado.
SELECT rep, AVG(importe) AS [Importe medio]
FROM pedidos
GROUP BY rep;
Resultado:
rep Importe medio
101

88,76

102

25,92

103

21,00

105

154,5492

106

23,04

107

114,7733

108

40,9042

109

35,525

110

159,6066

Repetir la consulta pero para que tambin salgan los empleados que no han vendido nada.
SELECT numemp, AVG(importe) AS [Importe medio]
FROM pedidos RIGHT JOIN empleados ON rep = numemp
GROUP BY numemp;
Resultado:
rep Importe medio
101

88,76

102

25,92

Ing. Jos Rodrguez Mantilla

Pgina 36

Material de Clase SQL


103

21,00

104

NULL

105

154,5492

106

23,04

107

114,7733

108

40,9042

109

35,525

110

159,6066

111

NULL

112

NULL

113

NULL

114

NULL

Cul es en cada una de las oficinas, el rango de cuotas asignadas a sus vendedores?
SELECT oficinas.oficina, MIN(cuota) AS [Cuota mnima], MAX(cuota) AS [Cuota mxima]
FROM oficinas LEFT JOIN empleados ON empleados.oficina = oficinas.oficina
GROUP BY oficinas.oficina;
Resultado:
oficina Cuota mnima Cuota mxima
11

27500,00

27500,00

12

20000,00

30000,00

13

35000,00

40000,00

21

10000,00

35000,00

22

30000,00

30000,00

23

NULL

NULL

Ing. Jos Rodrguez Mantilla

Pgina 37

Material de Clase SQL


24

NULL

NULL

25

NULL

NULL

26

NULL

NULL

27

NULL

NULL

28

NULL

NULL

29

NULL

NULL

30

NULL

NULL

31

NULL

NULL

Listar cuntos empleados estn asignados a cada oficina, incluso las que no tienen.
SELECT oficinas.oficina, COUNT(numemp) AS Empleados
FROM oficinas LEFT JOIN empleados ON empleados.oficina = oficinas.oficina
GROUP BY oficinas.oficina;
Resultado:
oficina Empleados
11

12

13

21

22

23

24

25

26

27

Ing. Jos Rodrguez Mantilla

Pgina 38

Material de Clase SQL


28

29

30

31

Listar cuntos clientes son atendidos por cada empleado (el cliente ha realizado un pedido
con l).
SELECT rep, COUNT(DISTINCT clie) AS [Clientes atendidos]
FROM pedidos
GROUP BY rep;
Resultado:
rep

Clientes
atendidos

101

102

103

105

106

107

108

109

110

5.15. Seleccin sobre grupos de filas, la clusula HAVING


Cuando queremos incluir una clusula de seleccin sobre las filas del origen, utilizamos la clusula
WHERE, pero cuando estamos definiendo una consulta de resumen, no podemos utilizar esta
clusula para seleccionar filas del resultado ya que cada una de stas representa un grupo de filas
de la tabla original. Para seleccionar filas del resumen tenemos la clusula HAVING.

Ing. Jos Rodrguez Mantilla

Pgina 39

Material de Clase SQL


HAVING condicin de bsqueda
HAVING funciona igual que la clusula WHERE pero en vez de actuar sobre las filas del origen de
datos, acta sobre las filas del resultado, selecciona grupos de filas por lo que la condicin de
bsqueda sufrir alguna limitacin, la misma que para la lista de seleccin:
Ejemplo:
SELECT oficina, count(numemp) AS [Nmero de empleados]
FROM empleados
GROUP BY oficina
HAVING COUNT(numemp)<2;
Resultado:
oficina Nmero de empleados
13

22

Esta SELECT es la misma que la del primer ejemplo del apartado sobre la clusula GROUP BY, la
diferencia es que le hemos aadido la clusula HAVING, que hace que del resultado slo se
visualicen los grupos que cumplan la condicin. Es decir slo aparecen las oficinas que tienen
menos de 2 empleados.
Siempre que en una condicin de seleccin haya una funcin de columna, la condicin deber
incluirse en la clusula HAVING, adems, como HAVING filtra filas del resultado, slo puede
contener expresiones (nombres de columnas, expresiones, funciones) que tambin pueden
aparecer en la lista de seleccin, por lo que tambin se aplica la misma regla a no olvidar:
EN LA CLUSULA HAVING UN NOMBRE DE COLUMNA NO PUEDE APARECER FUERA DE UNA
FUNCIN DE AGREGADO SI NO ES UNA COLUMNA DE AGRUPACIN.
Las expresiones que pongamos en HAVING no tienen porqu aparecer en la lista de seleccin, por
ejemplo en la SELECT anterior se poda haber escrito:
HAVING SUM(ventas)=10000
Para practicar puedes realizar este Ejercicio Seleccin sobre agrupaciones con HAVING.
Nota: Para realizar los ejercicios, utiliza la base de datos GestionSimples.

Objetivo
Filtrar los resultados de una consulta de resumen con GROUP BY, mediante la clusula HAVING.

Ejercicio paso a paso


Ing. Jos Rodrguez Mantilla

Pgina 40

Material de Clase SQL


Para cada empleado cuyos pedidos suman ms de 300 euros, hallar el importe medio vendido.
SELECT rep, AVG(importe) AS [Importe medio]
FROM pedidos
GROUP BY rep
HAVING SUM(importe) > 300;
Resultado:
rep Importe medio
105

154,5492

107

114,7733

110

159,6066

Si quisiramos que adems aparezca el nombre del empleado:


SELECT rep, nombre, AVG(importe) AS [Importe medio]
FROM empleados INNER JOIN pedidos ON numemp = rep
GROUP BY rep, nombre
HAVING SUM(importe) > 300;
rep

nombre

Importe medio

105

Vicente Pantalla

154,5492

107

Jorge Gutirrez

114,7733

110

Juan Victor

159,6066

Por cada oficina con 2 o ms personas, calcula la cuota total y las ventas totales de todos los
empleados que trabajan en la oficina, de la oficina queremos el nmero y la ciudad.
SELECT oficinas.oficina, ciudad, SUM(cuota) AS [Cuota total], SUM(empleados.ventas) AS ventas
FROM empleados INNER JOIN oficinas ON empleados.oficina = oficinas.oficina
GROUP BY oficinas.oficina, ciudad
HAVING COUNT(*) > 2;
Resultado:

Ing. Jos Rodrguez Mantilla

Pgina 41

Material de Clase SQL


oficina

ciudad

Cuota total

ventas

12

Alicante

77500,00

73400,00

21

Badajoz

80000,00

143500,00

Ejercicios unidad 5: Consultas de resumen


Para realizar los ejercicios, debers utilizar la base de datos GestionSimples.

Ejercicio 1: Funciones de agregado


1.

Cuntas oficinas tenemos en Valencia?


Resultado:
Valencianas
4

2.

Hallar cuntos pedidos hay de ms de 250 euros.


Resultado:
Superiores a 250
4

3.

Cuntos ttulos (cargos) de empleados se usan?


Resultado:
Cuntos ttulos
3

4.

Entre qu cuotas se mueven los empleados?


Resultado:
Cuota mnima Cuota mxima
3000,00

35000,00

Puedes consultar aqu las soluciones propuestas.

Ejercicio 2: Agrupamiento de filas: GROUP BY


1.

De cada vendedor (todos) queremos saber su nombre y el importe total vendido. En caso de
que el importe sea NULL, cambiarlo por 0,00 con la funcin ISNULL().
Resultado:

Ing. Jos Rodrguez Mantilla

Pgina 42

Material de Clase SQL


numemp

2.

nombre

Importe vendido

101

Antonio Viguer

266,28

102

Alvaro Jaumes

77,76

103

Juan Rovira

21,00

104

Jos Gonzlez

0,00

105

Vicente Pantalla

772,746

106

Luis Antonio

46,08

107

Jorge Gutirrez

344,32

108

Ana Bustamante

286,33

109

Mara Sunta

71,05

110

Juan Victor

478,82

111

Juan Gris

0,00

112

Julin Martorell

0,00

113

Juan Gris

0,00

114

Pablo Moreno

0,00

De cada empleado, obtener el importe vendido a cada cliente.


Resultado:
rep Cliente Importe vendido

3.

106

2101

14,58

101

2102

39,78

105

2103

735,296

102

2106

40,26

110

2107

28,82

101

2108

1,50

109

2108

71,05

107

2109

313,50

103

2111

21,00

105

2111

37,45

108

2112

29,25

110

2112

450,00

101

2113

225,00

108

2114

221,00

106

2117

31,50

108

2118

36,08

102

2120

37,50

107

2124

30,82

Repetir la consulta anterior pero ahora deben aparecer tambin los empleados que no han
vendido nada.
Resultado:

Ing. Jos Rodrguez Mantilla

Pgina 43

Material de Clase SQL


rep Cliente Importe vendido

4.

101

2102

39,78

101

2108

1,50

101

2113

225,00

102

2106

40,26

102

2120

37,50

103

2111

21,00

104

NULL

NULL

105

2103

735,296

105

2111

37,45

106

2101

14,58

106

2117

31,50

107

2109

313,50

107

2124

30,82

108

2112

29,25

108

2114

221,00

108

2118

36,08

109

2108

71,05

110

2107

28,82

110

2112

450,00

111

NULL

NULL

112

NULL

NULL

113

NULL

NULL

114

NULL

NULL

Repetir la consulta pero ahora debe aparecer tambin el total de cunto ha vendido cada
empleado. (Recuerda una opcin de la clusula GROUP BY)
Resultado:
rep

clie

Importe vendido

NULL

NULL

2364,386

101

NULL

266,28

101

2102

39,78

101

2108

1,50

101

2113

225,00

102

NULL

77,76

102

2106

40,26

102

2120

37,50

103

NULL

21,00

103

2111

21,00

104

NULL

NULL

104

NULL

NULL

105

NULL

772,746

Ing. Jos Rodrguez Mantilla

Pgina 44

Material de Clase SQL

5.

105

2103

735,296

105

2111

37,45

106

NULL

46,08

106

2101

14,58

106

2117

31,50

107

NULL

344,32

107

2109

313,50

107

2124

30,82

108

NULL

286,33

108

2112

29,25

108

2114

221,00

108

2118

36,08

109

NULL

71,05

109

2108

71,05

110

NULL

478,82

110

2107

28,82

110

2112

450,00

111

NULL

NULL

111

NULL

NULL

112

NULL

NULL

112

NULL

NULL

113

NULL

NULL

113

NULL

NULL

114

NULL

NULL

114

NULL

NULL

En los resultados anteriores no se distinguen bien las lneas que corresponden a totales.
Modificar la consulta para obtener este resultado:
Importe vendido

Agrupa Agrupa
clie numemp

NULL

2364,386

101

NULL

266,28

101

2102

39,78

101

2108

1,50

101

2113

225,00

102

NULL

77,76

102

2106

40,26

102

2120

37,50

103

NULL

21,00

103

2111

21,00

104

NULL

NULL

104

NULL

NULL

rep

clie

NULL

Ing. Jos Rodrguez Mantilla

Pgina 45

Material de Clase SQL


...
6.

....

... (sigue)

...

...

Ahora modifica la consulta para que las filas de totales aparezcan ms claras. (Recuerda la
funcin CASE)
Resultado:

7.

rep

clie

Importe vendido

NULL

NULL

2364,386

Total empleado

101

NULL

266,28

Total empleado

101

2102

39,78

101

2108

1,50

101

2113

225,00

102

NULL

77,76

102

2106

40,26

102

2120

37,50

103

NULL

21,00

103

2111

21,00

104

NULL

NULL

104

NULL

NULL

Total empleado

...

....

... (sigue)

...

Agrupa
numemp

Agrupa clie

Total final

Total empleado

Total empleado

...

Ahora coloca las columnas Agrupa delante de las dems columnas:


Resultado:
Agrupa
numemp
Total final

Agrupa clie

rep

clie

Total empleado

NULL

NULL

2364,386

Total empleado

101

NULL

266,28

101

2102

39,78

101

2108

1,50

101

2113

225,00

102

NULL

77,76

102

2106

40,26

102

2120

37,50

103

NULL

21,00

103

2111

21,00

104

NULL

NULL

Total empleado

104

NULL

NULL

...

...

....

...

Total empleado

Total empleado

... (sigue)

Ing. Jos Rodrguez Mantilla

Importe vendido

Pgina 46

Material de Clase SQL


8.

Ahora queremos que "Total empleado" aparezca en la columna clie. Piensa primero en
cuntas columnas quieres y luego en cada columna que tiene que salir.
Resultado:
Agrupa
numemp
numemp
Total final

... (sigue)

9.

clie

Importe vendido

NULL

Total empleado

2364,386

101

Total empleado

266,28

101

2102

39,78

101

2108

1,50

101

2113

225,00

102

Total empleado

77,76

102

2106

40,26

102

2120

37,50

103

Total empleado

21,00

103

2111

21,00

104

NULL

NULL

104

Total empleado

NULL

...

....

...

El empleado 104 (y otros) no ha vendido a nadie y por eso sale en la columna clie la palabra
NULL, queremos que en estos casos no aparezca nada (se deje en blanco), y el importe si es
NULL que salga un cero.
Resultado:
Agrupa
numemp
numemp
Total final

clie

NULL

Total empleado

2364,386

101

2102

39,78

101

2108

1,50

101

2113

225,00

101

Total empleado

266,28

102

2106

40,26

102

2120

37,50

102

Total empleado

77,76

103

2111

21,00

103

Total empleado

21,00

104
... (sigue)

Importe vendido

0,00

104

Total empleado

0,00

...

....

...

Nota: Recuerda la funcin ISNULL() (para la columna importe vendido) y la funcin


CASE con diferentes condiciones (para la columna clie).

Ing. Jos Rodrguez Mantilla

Pgina 47

Material de Clase SQL


10. Lo rematamos para que el resultado quede as:
numemp
Total final

clie
...

2364,386

101

2102

39,78

101

2108

1,50

101

2113

225,00

101

Total empleado

266,28

102

2106

40,26

102

2120

37,50

102

Total empleado

77,76

103

2111

21,00

103

Total empleado

21,00

104
... (sigue)

Importe vendido

...

0,00

104

Total empleado

0,00

...

....

...

Ayuda ejercicios unidad 5: Consultas de resumen


Ejercicio 1: Funciones de agregado
1. Cuntas oficinas tenemos en Valencia?
SELECT COUNT(*) AS Valencianas
FROM oficinas
WHERE ciudad = 'Valencia';
2. Hallar cuntos pedidos hay de ms de 250 euros.
SELECT COUNT(*) AS [Superiores a 250]
FROM pedidos
WHERE importe > 250;
3. Cuntos ttulos (cargos) de empleados se usan?
SELECT COUNT(DISTINCT titulo) AS [Cuntos ttulos]
FROM empleados;
4. Entre qu cuotas se mueven los empleados?
SELECT MIN(cuota) AS [Cuota mnima], MAX(cuota) AS [Cuota mxima]
FROM empleados;

Ing. Jos Rodrguez Mantilla

Pgina 48

Material de Clase SQL


Ejercicio 2: Agrupamiento de filas: GROUP BY
1. De cada vendedor (todos) queremos saber su nombre y el importe total vendido. En caso
de que el importe sea NULL, cmbialo por 0,00 con la funcin ISNULL().
SELECT numemp, nombre, ISNULL(SUM(importe),0) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, nombre;
2. De cada empleado, obtener el importe vendido a cada cliente.
SELECT rep, clie AS Cliente, SUM(importe) AS [Importe vendido]
FROM pedidos
GROUP BY rep, clie;
3. Repetir la consulta anterior pero ahora deben aparecer tambin los empleados que no han
vendido nada.
SELECT numemp, clie, SUM(importe) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie
ORDER BY numemp,clie;
4. Repetir la consulta pero ahora debe aparecer tambin el total de cunto ha vendido cada
empleado.
SELECT numemp, clie, SUM(importe) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
5. En los resultados anteriores no se distinguen bien las lneas que corresponden a totales.
Modificar la consulta para indicar con un 1 si es una fila de totales y con un 0 si no lo es.
SELECT numemp, clie, SUM(importe) AS [Importe vendido], GROUPING(clie) AS [Agrupa clie],
GROUPING(numemp) AS [Agrupa numemp]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;

Ing. Jos Rodrguez Mantilla

Pgina 49

Material de Clase SQL


6. Ahora modifica la consulta para que las filas de totales aparezcan ms claras,
substituyendo el 1 de Agrupa clie por "Total empleado", el 1 de Agrupa numemp por Total final y el
valor 0 por espacio en blanco.
SELECT numemp, clie, SUM(importe) AS [Importe vendid o],
CASE GROUPING(clie) WHEN 0 THEN ' ' WHEN 1 THEN 'Total empleado' END AS [Agrupa clie],
CASE GROUPING(numemp) WHEN 0 THEN ' ' ELSE 'Total Final' END AS [Agrupa numemp]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
7. Ahora coloca las columnas Agrupa delante de las dems columnas.
SELECT CASE GROUPING(numemp) WHEN 0 THEN ' ' ELSE 'Total Final' END AS [Agrupa numemp],
CASE GROUPING(clie) WHEN 0 THEN ' ' WHEN 1 THEN 'Total empleado' END AS [Agrupa clie],
numemp, clie, SUM(importe) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
8. Ahora queremos que "Total empleado" aparezca en la columna clie.
SELECT CASE GROUPING(numemp) WHEN 0 THEN ' ' ELSE 'Total Final' END AS [Agrupa numemp],
numemp,
CASE GROUPING(clie) WHEN 0 THEN CONVERT(CHAR(4),clie) WHEN 1 THEN 'Total empleado'
END AS [Clie],
SUM(importe) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
9. El empleado 104 (y otros) no ha vendido a nadie y por eso sale en la columna clie la palabra
NULL, queremos que en estos casos no aparezca nada (se deje en blanco), y el importe si es NULL
que salga un cero.
SELECT CASE GROUPING(numemp) WHEN 0 THEN ' ' ELSE 'Total Final' END AS [Agrupa numemp],
numemp,
CASE WHEN GROUPING(clie) = 1 THEN 'Total empleado' WHEN clie IS NULL THEN ' ' ELSE
CONVERT(CHAR(4),clie) END AS [Clie],
ISNULL(SUM(importe),0) AS [Importe vendido]

Ing. Jos Rodrguez Mantilla

Pgina 50

Material de Clase SQL


FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;
10. Lo rematamos para que la fila del Total final no muestre los valores "NULL" ni "Total
empleado". En cambio, los cambiaremos por tres puntos. Tampoco mostraremos el encabezado
"Agrupa numemp".
SELECT CASE GROUPING(numemp) WHEN 0 THEN ' ' ELSE 'Total Final' END AS [ ],
ISNULL(CONVERT(CHAR(3),numemp),'... ') AS [numemp],
CASE WHEN GROUPING(clie) = 1 AND GROUPING(numemp) = 0
THEN 'Total empleado' WHEN GROUPING(clie) = 1
AND GROUPING(numemp) = 1 THEN '...'
WHEN clie IS NULL THEN ' ' ELSE CONVERT(CHAR(4),clie) END AS [Clie],
ISNULL(SUM(importe),0) AS [Importe vendido]
FROM empleados LEFT JOIN pedidos ON numemp = rep
GROUP BY numemp, clie WITH ROLLUP
ORDER BY numemp,clie;

Ing. Jos Rodrguez Mantilla

Pgina 51

Potrebbero piacerti anche