You are on page 1of 38

Power Builder + Sql

Power Builder + Sql

Consultas simples

[INTO nueva_tabla]
[FROM { <origen> } [ ,...n ] ]

3.1. Introduccin

[WHERE <condicion_busqueda> ]
Vamos a empezar por la instruccin que ms se utiliza en SQL, la sentencia SELECT. La
sentencia SELECT es, con diferencia, la ms compleja y potente de las sentencias SQL, con
ella podemos recuperar datos de una o ms tablas, seleccionar ciertos registros e incluso
obtener resmenes de los datos almacenados en la base de datos. Es tan compleja que la
estudiaremos a lo largo de varias unidades didcticas incorporando poco a poco nuevas
funcionalidades.

[GROUP BY [ ALL ] expresion_agrupacion [ ,...n ]


[WITH { CUBE | ROLLUP } ]
]
[HAVING < condicion_busqueda > ]

El resultado de una SELECT es una tabla lgica que alberga las filas resultantes de la
ejecucin de la sentencia.
Debido a la complejidad de la sentencia (en la sintaxis anterior no se han detallado algunos
elementos), la iremos viendo poco a poco, empezaremos por ver consultas bsicas para luego
ir aadiendo ms clusulas.

La sintaxis completa es la siguiente:

SELECT sentencia::=[WITH

Empezaremos por ver las consultas ms simples, basadas en una sola tabla y nos
limitaremos a la siguiente sintaxis:

<expresion_tabla_comun> [,...n]]

<expresion_consulta>
[ORDER BY {expression_columna|posicion_columna [ASC|DESC] }

SELECT [ALL|DISTINCT]

[ ,...n ]]

[TOP expresion [PERCENT] [WITH TIES]]

[COMPUTE

<lista_seleccion>

{{AVG|COUNT|MAX|MIN|SUM}
expression[ ,...n ]]

(expression)}[

,...n

[BY

FROM
[WHERE

<origen>

<condicion_busqueda> ]

[ORDER BY {expression_columna|posicion_columna [ASC|DESC]} [ ,...n

[<FOR clausula_for>]

]]

[OPTION (<query_hint>[ ,...n ])]


<expresion_consulta> ::=

3.2. Origen de datos FROM

{<especificacion_consulta>
[ {UNION

| ( < expresion_consulta > ) }

[ALL]|EXCEPT|INTERSECT}

<especificacion_consulta> |

(<expresion_consulta>) [...n

De la sintaxis anterior, el elemento <origen> indica de dnde se va a extraer la informacin


y se indica en la clusula FROM, es la nica clusula obligatoria. En este tema veremos un
origen de datos basado en una sola tabla.
La sintaxis ser la siguiente:

]
<especificacion_consulta> ::=

<origen>::= nb_tabla | nb_vista [[ AS ] alias_tabla ]

SELECT [ALL|DISTINCT]
[TOP expresion [PERCENT] [WITH TIES] ]

nb_tabla representa un nombre de tabla.

<lista_seleccion>
nb_vista un nombre de vista.
Lic. Vladimir Cotaquispe Gutirrez. 1

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 2

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Tanto para las tablas como para las vistas, podemos hacer referencia a tablas que estn en
otras bases de datos (siempre que tengamos los permisos adecuados), en este caso tenemos
que cualificar el nombre de la tabla, indicando delante el nombre de la base de datos (Lgica) y
el nombre del esquema al que pertenece la tabla dentro de la base de datos.

Power Builder + Sql

En la lista de seleccin <lista_seleccion> indicamos las columnas que se tienen que


visualizar en el resultado de la consulta.

<lista_seleccion> ::=
Por ejemplo: MiBase.dbo.MiTabla se refiere a la tabla MiTabla que se encuentra en el
esquema dbo de la base de datos MiBase.

*
| {nombre_tabla|nombre_vista|alias_tabla}.*

Cuando no se definen esquemas, SQL-Server crea uno por defecto en cada base de datos
denominado dbo.
Opcionalmente podemos definir un nombre de alias.

| { [{nombre_tabla|nombre_vista|alias_tabla}.]
{nb_columna|$IDENTITY|$ROWGUID}
|<expresion>

Un nombre de alias (alias_tabla) es un nombre alternativo que se le da a la tabla dentro de


la consulta.

}[[AS] alias_columna]
| alias_columna = <expresion>

Si se define un nombre de alias, dentro de la consulta, ser el nombre a utilizar para


referirnos a la tabla, el nombre original de la tabla ya no tendr validez.
Se utilizan los nombres de alias para simplificar los nombres de tablas a veces largos y
tambin cuando queremos combinar una tabla consigo misma; ya volveremos sobre los alias
de tabla cuando veamos consultas multitabla.
La palabra AS no aade ninguna operatividad, est ms por esttica.

} [ ,...n ]

Separamos la definicin de cada columna por una coma y las columnas del resultado
aparecern en el mismo orden que en la lista de seleccin.
Para cada columna del resultado su tipo de datos, tamao, precisin y escala son los
mismos que los de la expresin que da origen a esa columna.

Podemos escribir:
Podemos definir las columnas del resultado de varias formas, mediante:
SELECT ...
FROM tabla1

Una expresin simple:


Sacamos los datos de la tabla tabla1

SELECT ...
FROM tabla1 t1
Sacamos
asignamos un alias de tabla: t1

los datos de la tabla tabla1 y le

SELECT ...
FROM tabla1 AS t1

Es

equivalente a la sentencia anterior.

una referencia a una funcin.

una variable local

una constante

una columna del origen de datos,

Una subconsulta escalar, que es otra instruccin SELECT que devuelve un nico valor y
se evala para cada fila del origen de datos (esto no lo veremos de momento).

Si la tabla o la vista estn en otra base de datos del mismo equipo que est ejecutando la
instancia de SQL Server, se utiliza el nombre cualificado con el formato
nbBaseDatos.nbEsquema.nbTabla.

Una expresin compleja generada al usar operadores en una o ms expresiones


simples.

Si la tabla o la vista estn fuera del servidor local en un servidor vinculado, se utiliza un
nombre de cuatro partes con el formato nbservidor.catalogo.nbEsquema.nbTabla.
Volveremos ms adelante sobre las conexiones remotas.

La asignacin de variables con el formato @variable_local = expresin.

La palabra clave *.

La palabra clave $IDENTITY.


La palabra clave $ROWGUID.

3.3. La lista de seleccin


Lic. Vladimir Cotaquispe Gutirrez. 3

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 4

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

3.4. Columnas del origen de datos

Idfab

Cuando queremos indicar en la lista de seleccin una columna del origen de datos, la
especificamos mediante su nombre simple o nombre cualificado. El nombre cualificado consiste
en el nombre de la columna precedido del nombre de la tabla donde se encuentra la columna.
Si en el origen de datos hemos utilizado una vista o un nombre de alias, deberemos utilizar
ese nombre. Es obligatorio utilizar el nombre cualificado cuando el nombre de la columna
aparece en ms de una tabla del origen de datos.
Ejemplos de consulta simple.
Listar nombres, oficinas, y fechas de contrato de todos los empleados:

SELECT
FROM

nombre, oficina, contrato

descripcion

precio

aci

41001

arandela

0,58

aci

41002

bisagra

0,80

aci

41003

art t3

1,12

aci

41004

art t4

1,23

aci

4100x

junta

0,26

aci

4100y

extractor

28,88

aci

4100z

mont

26,25

bic

41003

manivela

6,52

bic

41089

rodamiento

2,25

3.5. Alias de columna

empleados;
Por defecto, en el encabezado de cada columna del resultado, aparece el nombre de la
columna origen, pero esto se puede cambiar definiendo un alias de columna, el alias de
columna es un nombre alternativo que se le da a esa columna.

El resultado sera:
nombre

oficina

contrato

Antonio Viguer

12

1986-10-20

Alvaro Jaumes

21

1986-12-10

Juan Rovira

12

1987-03-01

Jos Gonzlez

12

1987-05-19

Vicente Pantalla

13

1988-02-12

Luis Antonio

11

1988-06-14

Jorge Gutirrez

22

1988-11-14

Ana Bustamante

21

1989-10-12

Mara Sunta

11

1999-10-12

Juan Victor

NULL

1990-01-13

Listar una tarifa de productos:

SELECT
FROM

idproducto

El alias de columna se indica mediante la clusula AS. Se escribe el nuevo texto tal cual sin
comillas siguiendo las reglas de los identificadores.
Ejemplo:

SELECT numclie,nombre AS

nombrecliente

FROM clientes;

El resultado ser :
Numclie

nombrecliente

2101

Luis Garca Antn

2102

Alvaro Rodrguez

2103

Jaime Llorens

idfab, idproducto, descripcion, productos.precio


productos;

Hemos cualificado la columna precio aunque no es necesario en este caso.

en vez de:

El resultado sera:
Lic. Vladimir Cotaquispe Gutirrez. 5

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 6

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Numclie

nombre

Power Builder + Sql

DATEPART

Devuelve un entero que corresponde a la parte de la fecha solicitada.

2101

Luis Garca Antn

DAY

Devuelve el da de la fecha indicada.

2102

Alvaro Rodrguez

MONTH

Devuelve el mes de la fecha indicada.

2103

Jaime Llorens

YEAR

Devuelve el ao de la fecha indicada.

DATENAME

Devuelve una cadena de caracteres que representa el valor de la


unidad especificada de una fecha especificada.

DATEADD

Devuelve un valor datetime nuevo que resulta de sumar un intervalo de


tiempo a una fecha especificada.>

DATEDIFF

Devuelve el n de intervalos que hay entre dos fechas.

@@DATEFIRST

Devuelve el primer da de la semana establecido con SET DATEFIRST.

SET
DATEFIRST

Establece el primer da de la semana en un nmero del 1 al 7.

La palabra AS es opcional.

SELECT numclie,nombre nombrecliente


FROM clientes;

Sera equivalente a la consulta anterior


Si queremos incluir espacios en blanco en el nombre lo debemos encerrar entre corchetes.

SELECT numclie,nombre AS [nombre cliente]


Funciones de cadena:

FROM clientes;

Funcin
Nota importante: Este nombre de alias se podr utilizar en la lista de seleccin y en la
clusula ORDER BY pero no en la clusula WHERE.

3.6. Funciones
Existen funciones que podemos utilizar en la lista de seleccin, e incluso en otras clusulas
que veremos ms adelante, como el WHERE. Las principales funciones son las siguientes:
Funciones de fecha:
Funcin
GETDATE
GETUTCDATE

Descripcin
Devuelve la fecha actual.
Devuelve la hora UTC.

Lic. Vladimir Cotaquispe Gutirrez. 7

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Descripcin

ASCII

Devuelve el valor de cdigo ASCII del carcter situado ms a la izquierda


de una expresin de caracteres.

CHAR

Devuelve el carcter ASCII del entero indicado.

NCHAR

Devuelve el carcter Unicode del entero indicado.

UNICODE

Devuelve el entero que se corresponde al carcter Unicode indicado.

LEN

Devuelve el total de caracteres de una cadena, excluidos los espacios en


blanco finales.

LTRIM

Devuelve una cadena tras quitarle los espacios en blanco iniciales.

RTRIM

Devuelve una cadena tras quitarle los espacios en blanco finales.

LEFT

Devuelve los N ltimos caracteres de una cadena.

RIGHT

Devuelve los N primeros caracteres de una cadena.

SUBSTRING

Devuelve parte de una expresin.

LOWER

Devuelve la cadena convertida a minsculas.

UPPER

Devuelve la cadena convertida a maysculas.

REPLACE

Reemplaza una determinada cadena.

Lic. Vladimir Cotaquispe Gutirrez. 8

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

STUFF

Elimina el nmero de caracteres especificado e inserta otro conjunto de


caracteres en el punto de inicio indicado.

QUOTENAME

Devuelve una cadena Unicode con los delimitadores agregados para


convertirla en un identificador delimitado vlido de Microsoft SQL Server
2005.

SPACE

Devuelve una cadena de espacios repetidos.

STR

Devuelve una cadena de caracteres a partir de datos numricos.

REPLICATE

Repite una cadena N veces.

REVERSE

Devuelve una cadena invertida.

CHARINDEX

Devuelve la posicin inicial de la expresin especificada en una cadena


de caracteres.

PATINDEX

Devuelve la posicin inicial de la primera repeticin de un patrn en la


expresin especificada, o ceros si el patrn no se encuentra, en todos los
tipos de datos de texto y caracteres.

Otras funciones:
Funcin

Descripcin

ROUND

Redondea un valor a la longitud y precisin indicadas.

CAST
CONVERT

Power Builder + Sql

El resultado ser:
ciudad

region

superavit

Valencia

este

11800,00

Alicante

este

-6500,00

Castellon

este

1800,00

Badajoz

oeste

11100,00

A Corua

oeste

-11400,00

Madrid

centro

NULL

Madrid

centro

-10000,00

Pamplona

norte

NULL

Valencia

este

-90000,00

Convierten de un tipo de datos a otro de forma explcita.

CASE

Evala una lista de condiciones.

ISNULL

Reemplaza el valor NULL por otro especificado.

COALESCE

Devuelve la primera expresin distinta de NULL entre sus


argumentos.

3.7. Columnas calculadas

De cada producto queremos saber el id de fabricante, id de producto, su descripcin y el


valor de sus existencias.

SELECT

Adems de las columnas que provienen directamente de la tabla origen, una consulta SQL
puede incluir columnas calculadas cuyos valores se evalan a partir de una expresin.
La expresin puede contener cualquier operador vlido (+, -, *, /, &), cualquier funcin
vlida, nombres de columnas del origen de datos, nombres de parmetros o constantes y para
combinar varias operaciones se pueden utilizar los parntesis.

idfab,idproducto,descripcion,(existencias*precio) AS valoracion

FROM productos;

El resultado sera:
Idfab

idproducto

descripcion

valoracion

Ejemplos de columnas calculadas:


aci

41001

arandela

160,66

Listar la ciudad, regin y el supervit de cada oficina. Consideraremos el supervit como el


volumen de ventas que se encuentran por encima o por debajo del objetivo de la oficina.

aci

41002

bisagra

133,60

SELECT

aci

41003

art t3

231,84

FROM

ciudad, region, (ventas-objetivo) AS superavit


oficinas;

Lic. Vladimir Cotaquispe Gutirrez. 9

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 10

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

aci

41004

art t4

170,97

aci

4100x

junta

9,62

aci

4100y

extractor

722,00

aci

4100z

mont

735,00

bic

41003

manivela

19,56

bic

41089

rodamiento

175,50

Power Builder + Sql

21

tiene ventas de

83600,00

22

tiene ventas de

18600,00

23

tiene ventas de

NULL

24

tiene ventas de

15000,00

26

tiene ventas de

NULL

28

tiene ventas de

0,00

El incluir una constante como columna en la lista de seleccin puede parecer intil (se
repetir el mismo valor en todas las filas) pero veremos ms adelante que tiene utilidad en
ciertos casos.
Tambin podemos utilizar la sintaxis:

alias_columna = <expresion>
Listar el nombre, mes y ao del contrato de cada vendedor.
Ejemplo:
SELECT nombre, MONTH(contrato) AS
[Ao de contrato]

[Mes de contrato], YEAR(contrato) AS


SELECT oficina, superavit =

FROM

ventas-objetivo

empleados;
Esto tiene el mismo efecto que

El resultado ser:
Nombre

Mes de contrato

Ao de contrato

Antonio Viguer

10

1986

Alvaro Jaumes

12

1986

Juan Rovira

1987

SELECT oficina, ventas-objetivo AS

superavit

3.8. Utilizacin del asterisco *


Listar las ventas en cada oficina con el formato: 22 tiene ventas de 186,042.00
Si queremos visualizar todas las columnas del origen de datos, en lugar de indicar todas las
columnas una a una se puede utilizar el carcter de sustitucin *.
SELECT

oficina, 'tiene ventas de ' AS [ ], ventas


Mostrar todos los datos de la tabla oficinas.

FROM oficinas;

SELECT

El resultado sera:
FROM
oficina

oficinas;

ventas

11

tiene ventas de

69300,00

12

tiene ventas de

73500,00

13

tiene ventas de

36800,00

Lic. Vladimir Cotaquispe Gutirrez. 11

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Obtener todos los datos y el supervit de cada oficina.

Lic. Vladimir Cotaquispe Gutirrez. 12

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

SELECT
FROM

*, (ventas-objetivo) AS superavit

Power Builder + Sql

ORDER BY {expression_columna|posicion_columna [ASC|DESC]}[ ,...n ]

oficinas;

Tambin podemos cualificar el * con un nombre de tabla, de vista o un alias de tabla:

Podemos indicar una columna o varias separadas por una coma, la columna de ordenacin
se especifica mediante el nombre de columna en el origen de datos o su posicin dentro de la
lista de seleccin. Si utilizamos el nombre de columna, no hace falta que la columna aparezca
en la lista de seleccin. Si utilizamos la posicin es la posicin de la columna dentro de la lista
de seleccin empezando en 1.

SELECT oficinas.*
Por defecto la filas se ordenarn en modo ascendente (ASC), de menor a mayor; si
queremos invertir ese orden aadimos detrs de la columna la palabra DESC.

FROM oficinas;

Si la columna de ordenacin es alfanumrica, las filas se ordenarn por orden alfabtico.

oficinas.* se interpreta como: todas las columnas de la tabla oficinas.

Si la columna de ordenacin es numrica, las filas se ordenarn de menor a mayor.

Esta forma se utiliza normalmente cuando el origen est basado en varias tablas y queremos
indicar todas las columnas no del origen completo sino de una tabla concreta.

3.9. Las palabras clave $IDENTITY y $ROWGUID

Si la columna de ordenacin es de tipo fecha, las filas se ordenarn de ms antigua a


ms reciente o futura.
Ejemplos:

La palabra clave $IDENTITY se interpreta como la columna de la tabla que tiene la


propiedad IDENTITY (la columna de identidad que vimos en un tema anterior).

Mostrar las ventas de cada oficina, ordenadas por orden alfabtico de regin y dentro de
cada regin por ciudad.

Por ejemplo, si en la columna codigo de la tabla usuarios (BD Biblio) se ha definido la


propiedad IDENTITY.

SELECT
FROM

oficina, region, ciudad, ventas


oficinas

SELECT $IDENTITY, nombre, apellidos


ORDER

BY region, ciudad;

FROM usuarios;
Da como resultado:
Es equivalente a:
Oficina
SELECT codigo, nombre, apellidos
FROM usuarios;

La palabra clave $ROWGUID se interpreta como la columna de la tabla que tiene la


propiedad ROWGUIDCOL y se puede utilizar de la misma forma que $IDENTITY.

3.10. Ordenacin de las filas del resultado ORDER BY


Si queremos que las filas del resultado de la consulta aparezcan ordenadas, lo podemos
indicar mediante la clusula ORDER BY.

region

ciudad

ventas

24

centro

Aranjuez

15000,00

23

centro

Madrid

NULL

12

este

Alicante

73500,00

13

este

Castelln

36800,00

11

este

Valencia

69300,00

28

este

Valencia

0,00

26

norte

Pamplona

NULL

22

oeste

A Corua

18600,00

21

oeste

Badajoz

83600,00

Listar las oficinas de manera que las oficinas de mayores ventas aparezcan en primer lugar.
Lic. Vladimir Cotaquispe Gutirrez. 13

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 14

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

SELECT
FROM

ciudad, region, ventas

ORDER

oficinas
BY ventas DESC;

ciudad

region

Power Builder + Sql

este

Alicante

-6500,00

este

Valencia

-90000,00

norte

Pamplona

NULL

oeste

Badajoz

11100,00

oeste

A Corua

-11400,00

ventas

Badajoz

oeste

83600,00

Alicante

este

73500,00

Valencia

este

69300,00

Castellon

este

36800,00

A Corua

oeste

18600,00

Aranjuez

centro

15000,00

Valencia

este

0,00

Pamplona

norte

NULL

Madrid

centro

NULL

Listar las oficinas clasificadas en orden descendente de rendimiento de ventas, de modo que
las de mayor rendimiento aparezcan las primeras.

En este caso hemos utilizado el alias de columna para hacer referencia a la columna
calculada y tambin se puede observar que las filas aparecen ordenadas por regin ascendente
(no hemos incluido nada despus del nombre de la columna) y dentro de cada regin por
supervit y descendente.

3.11. Eliminar filas duplicadas DISTINCT/ALL


SQL no elimina las filas duplicadas en el resultado de la consulta, si nosotros no queremos
que
se
repitan
las
filas,
tenemos
la
clusula
DISTINCT.
Al incluir la clusula DISTINCT en la SELECT, se eliminar del resultado las repeticiones de
filas de resultado. Si por el contrario queremos que aparezcan todas las filas seleccionadas
podemos incluir la clusula ALL o nada, ya que ALL es el valor por defecto.
Listar los n de empleado de los directores de las oficinas.

SELECT
SELECT

dir

ciudad, region, ventas-objetivo


FROM oficinas;

FROM
ORDER

oficinas
BY 3 DESC;

dir
106

Lo mismo que el anterior pero agrupadas por regin.

104
105

SELECT

region, ciudad, (ventas-objetivo) AS superavit


108

FROM oficinas
108
ORDER BY region, superavit DESC;
108
108

Resultado:

NULL
Region

ciudad

superavit

centro

Aranjuez

-10000,00

centro

Madrid

NULL

este

Valencia

11800,00

este

Castelln

1800,00

Lic. Vladimir Cotaquispe Gutirrez. 15

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

NULL

Si un mismo empleado dirige varias oficinas (por ejemplo el 108), su cdigo aparece repetido
en el resultado. Para evitarlo modificamos la consulta:
Lic. Vladimir Cotaquispe Gutirrez. 16

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

SELECT DISTINCT dir

Power Builder + Sql

[TOP <expresin>

[PERCENT] [WITH TIES]]

FROM oficinas;
La clusula TOP indica que en el resultado no deben aparecer todas las filas resultantes
sino un cierto nmero de registros, las n primeras. Si la consulta incluye la clusula ORDER BY,
se realiza la ordenacin antes de extraer los n primeros registros.

dir
NULL

La expresin representa ese nmero n y debe devolver un nmero entero sin signo.
104
Por ejemplo tenemos la siguiente tabla:

105
106

SELECT

* FROM

productos:

108

Han desaparecido los valores duplicados.


Los que se eliminan son valores duplicados de filas del resultado, por ejemplo:

SELECT DISTINCT dir, region


FROM oficinas;

dir

region

NULL

este

NULL

norte

104

este

105

este

SELECT * FROM

106

este

ORDER BY ventas;

108

centro

108

oeste

Si ordenamos por ventas:

productos

Ahora el 108 aparece dos veces porque las dos filas donde aparece no son iguales (porque
tienen distinta regin).
NOTA: La clusula DISTINCT hace que la consulta tarde algo ms en ejecutarse debido al
proceso adicional de buscar y eliminar las repeticiones, por lo que se aconseja utilizarla
nicamente cuando sea imprescindible.

3.12. La clusula TOP


Obtenemos el siguiente resultado:
Lic. Vladimir Cotaquispe Gutirrez. 17

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 18

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

Si aadimos la clusula TOP:


SELECT TOP 10 oficina, ciudad,
SELECT TOP 3 *

FROM productos

ventas

FROM oficinas
ORDER BY ventas;

ORDER BY ventas

Obtenemos los 3 primeros registros:

Devuelve las 10 peores oficinas en cuanto a ventas: ordenamos las oficinas por ventas de
menor a mayor y sacamos las 10 primeras.
Si incluimos la palabra PERCENT, entonces n no indica el nmero de registros a recuperar
sino el porcentaje de registros a recuperar del total de filas recuperadas despus de ejecutar la
clusula WHERE.

SELECT TOP 50 PERCENT


Si existen ms registros con las mismas ventas que el ltimo valor de la lista, stos no
saldrn en el resultado de la consulta.

FROM productos
ORDER BY ventas

En el ejemplo el registro con cod = 2 no sale en el resultado y tiene las mismas ventas que
cod = 3.
Devuelve:
Si queremos que salgan aadimos la clusula WITH TIES. La clusula WITH TIES slo se
puede emplear si la SELECT incluye un ORDER BY, de lo contrario dar error.
Si aadimos la clusula WITH TIES:

SELECT TOP 3 WITH TIES *


FROM productos
Si el porcentaje no da exacto, siempre redondea al alza.

ORDER BY ventas

3.13. Seleccin de filas WHERE

Obtenemos:

La clusula WHERE se emplea para especificar las filas que se desean recuperar del origen
de datos.

WHERE <condicion_bsqueda>
<condicion_bsqueda> ::=
{ [NOT]<predicado>
Se incluyen en el resultado todos los registros que tienen ventas iguales al ltimo registro.

|(<condicion_bsqueda>)
}

Otro ejemplo:

[{AND|OR} [NOT] {<predicado>|(<condicion_bsqueda>)}]


Lic. Vladimir Cotaquispe Gutirrez. 19

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 20

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

una subconsulta escalar o


[ ...n ]
cualquier combinacin de nombres de columna, constantes y funciones conectados
mediante uno o varios operadores o una subconsulta.
En el resultado de la consulta slo aparecern las filas que cumplan que la condicin de
bsqueda sea TRUE, los valores NULL no se incluyen, por lo tanto, en las filas del resultado. La
condicin de bsqueda puede ser una condicin simple o una condicin compuesta por varias
condiciones (predicados) unidas por operadores AND y OR, no hay lmite en cuanto al nmero
de predicados que se pueden incluir. En las condiciones compuestas se pueden utilizar
parntesis para delimitar predicados y se aconseja su uso cuando se incluyen operadores AND
y OR en la misma condicin de bsqueda.

Ejemplo:
Listar los "buenos" vendedores (los que han rebasado su cuota).

SELECT numemp, nombre,

ventas, cuota

FROM empleados

3.14. Predicados

WHERE ventas > cuota


En SQL tenemos 7 tipos de predicados, condiciones bsicas de bsqueda:
numemp

Comparacin estndar

nombre

ventas

cuota

101

Antonio Viguer

30500,00

30000,00

Pertenencia a un conjunto (IN)

102

Alvaro Jaumes

47400,00

35000,00

Test de valor nulo (IS NULL).

103

Juan Rovira

28600,00

27500,00

Coincidencia con patrn (LIKE)

105

Vicente Pantalla

36800,00

35000,00

Si contiene (CONTAINS)

106

Luis Antonio

29900,00

27500,00

108

Ana Bustamante

36100,00

35000,00

109

Mara Sunta

39200,00

3000,00

Pertenencia a un intervalo (BETWEEN)

FREETEXT
Comparacin estndar.
Compara el valor de una expresin con el valor de otra. Para la comparacin se pueden
emplear = , <> , !=, < , <= , !<, > , >= ,!>

Las columnas que aparecen en el WHERE no tienen por qu aparecer en la lista de


seleccin, esta instruccin es igual de vlida:

Sintaxis:
SELECT numemp, nombre
<expresion>

{=|<>|!=|>|>=|!>|<|<=|!<} <expresion>
FROM empleados
WHERE ventas > cuota;

<expresion> Puede ser:

Hallar vendedores contratados antes de 1988.

Un nombre de columna,
una constante,
una funcin (inclusive la funcin CASE),

FROM empleados

una variable,
Lic. Vladimir Cotaquispe Gutirrez. 21

SELECT numemp, nombre, contrato

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 22

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

Pertenencia a un intervalo. BETWEEN

WHERE contrato < '01/01/1988';

<expresion> [NOT] BETWEEN <expresion2> AND <expresion3>


numemp

nombre

contrato

101

Antonio Viguer

1986-10-20

102

Alvaro Jaumes

1986-12-10

103

Juan Rovira

1987-03-01

104

Jos Gonzlez

1987-05-19

Examina si el valor de la expresin de test est en el rango delimitado por los valores
resultantes de expresion1 y expresion2, estos valores no tienen porqu estar ordenados en
ANSI/ISO; expresion1 debe ser menor o igual a expresion2.
Hallar vendedores cuyas ventas estn entre 20.000 euros y 50.000.

SELECT numemp, nombre, ventas


Tambin podemos utilizar funciones, sta es equivalente a la anterior:

FROM empleados
WHERE

ventas BETWEEN 20000 AND

100000;

SELECT numemp, nombre


FROM empleados

numemp

WHERE YEAR(contrato) < 1988;

nombre

ventas

101

Antonio Viguer

30500,00

102

Alvaro Jaumes

47400,00

103

Juan Rovira

28600,00

105

Vicente Pantalla

36800,00

106

Luis Antonio

29900,00

108

Ana Bustamante

36100,00

109

Mara Sunta

39200,00

La funcin YEAR(fecha) devuelve el ao de una fecha.


Hallar oficinas cuyas ventas estn por debajo del 80% de su objetivo:

SELECT
FROM

oficina
oficinas

WHERE

ventas < (.8 * objetivo);

Hallar las oficinas dirigidas por el empleado 108:

SELECT

oficina

FROM
WHERE

La instruccin anterior es equivalente a:

SELECT numemp, nombre, ventas

oficinas

FROM empleados

dir = 108;

WHERE

ventas >= 20000 AND ventas <=100000;

Parece que con BETWEEN se lee mejor.


Observa que no hemos utilizado separadores de millares (100.000), porque se habra
interpretado por una coma decimal.
Lic. Vladimir Cotaquispe Gutirrez. 23

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 24

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Test de pertenencia a conjunto IN


<expresion> IN (

Power Builder + Sql

WHERE oficina = NULL;

<exp_valor> [ ,...n ] )

Examina si el valor de la expresion es uno de los valores incluidos en la lista de valores


indicados entre parntesis. Se pueden expresar los valores mediante cualquier expresin, la
nica condicin es que todas las exp_valor devuelvan el mismo tipo de datos.

Esta instruccin no da error pero no obtiene lo que en principio parece que quiere obtener.
No obtenemos los empleados cuya oficina sea un valor nulo (es decir los empleados que no
tienen oficina), no obtenemos nada, en cambio los obtendremos utilizando el test de valor nulo:

SELECT numemp,nombre, oficina


Ejemplo:

FROM empleados

Obtener los empleados que trabajan en las oficinas 11, 20 o 22:

WHERE oficina IS NULL;

SELECT oficina, numemp, nombre

Resultado:

FROM empleados
numemp

nombre

oficina

WHERE oficina IN (11,20,22);


110
oficina

numemp

Juan Victor

NULL

nombre

11

106

Luis Antonio

22

107

Jorge Gutirrez

11

109

Mara Sunta

Juan Victor es el nico empleado que no tiene oficina asignada.


Listar los vendedores asignados a alguna oficina.

SELECT numemp, nombre, oficina


FROM empleados

Test de valor nulo IS NULL

WHERE oficina IS NOT NULL;

<expression> IS [NOT] NULL


numemp
Una condicin de bsqueda puede ser TRUE, FALSE o NULL/UNKNOW, este ltimo caso
se produce cuando algn campo que interviene en la condicin tiene valor NULL.
A veces es til comprobar explcitamente los valores NULL en una condicin de bsqueda ya
que estas filas puede que queramos darles un tratamiento especial, para ello tenemos el
predicado IS NULL.
Este test produce un valor TRUE o FALSE, por lo que se podr combinar con otras
condiciones. El valor NULL no es en s un valor por eso no lo podemos utilizar en una igualdad.

SELECT numemp,nombre
FROM empleados

Lic. Vladimir Cotaquispe Gutirrez. 25

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

nombre

oficina

101

Antonio Viguer

12

102

Alvaro Jaumes

21

103

Juan Rovira

12

104

Jos Gonzlez

12

105

Vicente Pantalla

13

106

Luis Antonio

11

107

Jorge Gutirrez

22

Lic. Vladimir Cotaquispe Gutirrez. 26

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

108

Ana Bustamante

21

109

Mara Sunta

11

Test de correspondencia con patrn LIKE

Power Builder + Sql

numemp

nombre

104

Jos Gonzlez

107

Jos Gonzlez

Obtiene los nombres que acaban en z.

Se utiliza cuando queremos comparar el valor de una columna con un patrn en el que se
utilice caracteres comodines.

SELECT numemp,nombre
FROM empleados

<expression>

[NOT] LIKE

<patron>

[ESCAPE 'car_escape']
WHERE nombre LIKE %on%;

Con expresin indicamos el valor a comparar (normalmente ser el nombre de una columna)
y patrn es la cadena que se busca. El patrn es de tipo texto y tiene que escribirse entre
comillas simples. Dentro del patrn podemos utilizar los siguientes comodines:
%

representa cualquier cadena de cero o ms caracteres.

SELECT numemp,nombre

numemp

nombre

101

Antonio Viguer

104

Jos Gonzlez

106

Luis Antonio

FROM empleados
Obtiene los nombres que contienen on.
WHERE nombre LIKE An%;
_
numemp

representa cualquier carcter (slo uno).

nombre

101

Antonio Viguer

108

Ana Bustamante

SELECT numemp,nombre
FROM empleados
WHERE nombre LIKE '__a%';

numemp

Obtiene todos los nombres que empiecen por An.

nombre

103

Juan Rovira

108

Ana Bustamante

110

Juan Victor

SELECT numemp,nombre
FROM empleados

Obtiene los nombres cuya tercera letra sea una a (en el patrn tenemos dos caracteres
subrayado).

WHERE nombre LIKE %z;

[
Lic. Vladimir Cotaquispe Gutirrez. 27

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

] sirve para indicar un carcter cualquiera perteneciente al conjunto indicando.


El conjunto se indica enumerando los caracteres o indicando un intervalo.

Lic. Vladimir Cotaquispe Gutirrez. 28

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

La clusula ESCAPE es opcional y permite definir un carcter de escape.


SELECT numemp,nombre
Un carcter de escape es un carcter que se coloca delante de un carcter comodn para
indicar que el comodn no debe interpretarse como tal, sino como un carcter normal.

FROM empleados
WHERE nombre LIKE '[a-d]%';

Obtiene los nombres que empiezan por cualquier letra de la a a la d.


Es equivalente a escribir:

Por ejemplo queremos buscar los nombres compuestos que incluyen un subrayado. En este
caso tenemos que poner el carcter _ como un carcter normal no como un comodn, as que lo
escribiremos as:

SELECT numemp,nombre
FROM empleados

SELECT numemp,nombre

WHERE nombre LIKE '%[_]%';


FROM empleados
WHERE nombre LIKE '[abcd]%';

[^] significa cualquier carcter individual que no se encuentre en el conjunto.

O bien,

SELECT numemp,nombre
FROM empleados

SELECT numemp,nombre

WHERE nombre LIKE '%!_%' ESCAPE '!';


FROM empleados
WHERE nombre LIKE '[^abcd]%';

Existen dos predicados ms para evaluar expresiones: CONTAINS y FREETEXT. Puedes


ver ms informacin sobre ellas en este avanzado .

Los predicados CONTAINS y FREETEXT (I)


SELECT numemp,nombre

CONTAINS

FROM empleados
WHERE nombre LIKE '[^a-d]%';

Se utiliza para buscar, coincidencias exactas o aproximadas con palabras o frases, palabras
prximas a otra dada en una cierta distancia, o coincidencias ponderadas.
CONTAINS puede buscar:

Obtienen los nombres que no empiecen por a, b, c ni d.


Es importante tener en cuenta que dentro del patrn el espacio en blanco es considerado
como un carcter ms, si colocamos dos espacios en el patrn, se buscarn dos espacios en el
campo.
Si queremos incluir en el patrn uno de los caracteres comodines y que no sea interpretado
como un comodn, sino como un carcter normal, lo tenemos que encerrar entre corchetes o
utilizar un carcter de escape.

Una palabra o una frase.


El prefijo de una palabra o una frase.
Una palabra cerca de otra palabra.
Una palabra que sea derivada de otra (por ejemplo, las palabras controles,
controladores, controlando y controlado son derivadas de control).
Una palabra que sea un sinnimo de otra palabra usando el diccionario de sinnimos
(por ejemplo, la palabra metal puede tener sinnimos como aluminio y acero).

[ESCAPE 'car_escape']
Lic. Vladimir Cotaquispe Gutirrez. 29

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 30

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

CONTAINS

} [

...n ]

{ nombre_columna | (lista_columnas) | * }
,

'< condicion_busqueda >'

[ , LANGUAGE idioma

< valor_ponderado > ::=

ISABOUT

< condicion_busqueda > ::=


{ < termino_simple
| < prefijo

{ {

< termino_simple >

>

| < prefijo >

>

| < generador >

| <

generador >

| < proximo >

| <

proximo >

| < valor_ponderado

>

[ WEIGHT ( peso )

} [ ,...n ]

| { ( <

condicion_busqueda > )

[ { < AND > | < AND NOT


< condicion_busqueda > [

> | < OR > } ]


...n ]
Nombre_columna es la columna donde se busca. Las columnas de tipo char, varchar,
nchar, nvarchar, text, ntext, image, xml y varbinary(max) son vlidas para la bsqueda de
texto.

}
< AND > ::= { AND | & }
< AND NOT > ::= { AND NOT | & !}
< OR > ::= { OR | | }
< termino_simple > ::=
palabra

| " frase "

< prefijo > ::=


{

Lista_columnas indica una lista de columnas separadas por comas.


El asterisco ( * ) especifica que todas las columnas de la tabla vlidas para bsquedas de
texto se deben utilizar en la condicin de bsqueda. Las columnas de la clusula CONTAINS
deben proceder de una sola tabla. Si en la clusula FROM hay ms de una tabla, * se tiene que
especificar con el nombre de la tabla.
Idioma Es el idioma en que el usuario genera la consulta.

"palabra * " | "frase *" }


Condicin bsqueda especifica el texto que se va a buscar y las condiciones para obtener
coincidencias.

< generador > ::=


FORMSOF

( { INFLECTIONAL | THESAURUS } , < termino_simple > [

,...n ] )

Frase es una o varias palabras con espacios entre cada una de ellas.

< proximo > ::=


{ <

termino_simple > | < prefijo > }

{ {

NEAR | ~ }

{ <

termino_simple > | < prefijo > }

Lic. Vladimir Cotaquispe Gutirrez. 31

Palabra es una cadena de caracteres sin espacios ni signos de puntuacin.

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Generador especifica la coincidencia de palabras cuando los trminos simples incluyen


variaciones de la palabra original que se busca para buscar palabras derivadas.

Lic. Vladimir Cotaquispe Gutirrez. 32

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

INFLECTIONAL especifica que se va a utilizar el analizador lingstico dependiente del


idioma en el trmino simple especificado. El comportamiento del analizador lingstico se define
en funcin de las reglas de anlisis lingstico de cada idioma concreto. El idioma neutro no
tiene ningn analizador lingstico asociado. El idioma de las columnas que se van a consultar
se utiliza para hacer referencia al analizador lingstico deseado. Si se especifica idioma, se
utiliza el analizador lingstico correspondiente a dicho idioma.

Lista_columnas indica una lista de columnas separadas por comas.

THESAURUS especifica que se utiliza el diccionario de sinnimos correspondiente al idioma


de texto de la columna o el idioma especificado en la consulta. El patrn o patrones ms largos
de termino_simple se hacen coincidir con el diccionario de sinnimos y se generan trminos
adicionales para expandir o reemplazar el patrn original.

Idioma Es el idioma en que el usuario genera la consulta.

El asterisco ( * ) especifica que todas las columnas de la tabla vlidas para bsquedas
de texto se deben utilizar en la condicin de bsqueda. Las columnas de la clusula
CONTAINS deben proceder de una sola tabla. Si en la clusula FROM hay ms de una
tabla, * se tiene que especificar con el nombre de la tabla.

Condicin bsqueda especifica el texto que se va a buscar y las condiciones para


obtener coincidencias.

Prximo especifica una coincidencia de palabras o frases que deben estar prximas entre
s. funciona de forma similar al operador AND: ambos requieren que existan varias palabras o
frases en la columna examinada.

Cadena_freetext es el texto que se va a buscar en nombre_columna. Se puede


escribir cualquier texto, incluidas palabras, frases y oraciones. Se generarn
coincidencias si se encuentra algn trmino o las formas de algn trmino en el ndice
de texto.

NEAR | ~ indica que la palabra o frase situada a la izquierda del operador NEAR o ~ tiene
que estar bastante cerca de la palabra o frase situada a la derecha del operador NEAR o ~. Se
pueden encadenar varios trminos de proximidad.

Si cadena_freetext se incluye entre comillas dobles, se realiza una bsqueda de frases


coincidentes, por lo que no se extraen las desinencias ni se utiliza el diccionario de
sinnimos.

<valor_ponderado> especifica que las filas coincidentes (devueltas por la consulta) coinciden
con una lista de palabras y frases a las que se asigna opcionalmente un valor ponderado.
WEIGHT(peso) especifica el valor de ponderacin como un nmero entre 0,0 y 1,0. Cada
componente de < valor_ponderado > puede incluir un peso.

Las consultas de bsqueda de texto que utilizan FREETEXT son menos precisas que las
consultas de texto que utilizan CONTAINS. El motor de bsqueda de texto de SQL Server
identifica las palabras y las frases importantes. No se le da significado especial a ninguna de las
palabras clave reservadas

3.15. Condiciones de bsqueda compuestas

FREETEXT
Es un predicado que se utiliza para buscar en columnas que contengan tipos de datos
basados en caracteres valores que coincidan con el significado y no literalmente con las
palabras de la condicin de bsqueda. Cuando se utiliza FREETEXT, el motor de consulta de
texto realiza internamente las siguientes acciones en freetext_string, asigna a cada uno de los
trminos un peso y busca las coincidencias.
Separa la cadena en palabras individuales basndose en lmites de palabras (separacin de
palabras).

En una clusula WHERE podemos incluir una condicin de bsqueda simple (formada por
un solo predicado) o compuesta (formada por la combinacin de predicados unidos por los
operadores lgicos NOT, AND, OR).
Cuando la condicin incluye varios operadores lgicos, el orden de prioridad de estos
operadores es:
NOT (el ms alto),
seguido de AND y OR (estos dos al mismo nivel).

Genera formas no flexionadas de las palabras (lematizacin).


Identifica una lista de expansiones o reemplazos de los trminos basndose en
coincidencias en el diccionario de sinnimos.

Como siempre, se pueden utilizar parntesis para alterar esta prioridad en una condicin de
bsqueda.

FREETEXT ( { nombre_columna | (list_columnas)

El orden de evaluacin de los operadores lgicos puede variar dependiendo de las opciones
elegidas por el optimizador de consultas.

| * }

, 'cadena_freetext' [ , LANGUAGE idioma

] )

Nombre_columna es la columna donde se busca. Las columnas de tipo char, varchar,


nchar, nvarchar, text, ntext, image, xml y varbinary(max) son vlidas para la
bsqueda de texto.
Lic. Vladimir Cotaquispe Gutirrez. 33

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Los operadores lgicos pueden devolver tres valores distintos: TRUE, FALSE, NULL
(UNKNOWN).
Tablas de verdad de los operadores:

Lic. Vladimir Cotaquispe Gutirrez. 34

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

AND Combina dos condiciones y se evala como TRUE cuando ambas condiciones son
TRUE.

Power Builder + Sql

FROM oficinas
WHERE NOT dir = 108;

AND

TRUE

FALSE

NULL

TRUE

TRUE

FALSE

NULL

FALSE

FALSE

FALSE

FALSE

NULL

NULL

FALSE

NULL

SELECT oficina
OR Combina dos condiciones y se evala como TRUE cuando alguna de las condiciones es
TRUE.

FROM oficinas
WHERE

OR

TRUE

FALSE

NULL

TRUE

TRUE

TRUE

TRUE

FALSE

TRUE

FALSE

NULL

NULL

TRUE

NULL

NULL

dir <> 108;

Devuelven:
oficina
11

NOT Niega la expresin booleana que especifica el predicado

12
13

NOT

TRUE

FALSE

NULL

FALSE

TRUE

NULL

Las oficinas sin director no aparecen, para que aparezcan deben aadir otro predicado:

Hallar los vendedores que estn por debajo de su cuota y tienen ventas inferiores a 30.000.

SELECT oficina, dir


FROM oficinas

SELECT nombre

WHERE NOT dir = 108 or dir is

FROM empleados
WHERE ventas < cuota AND ventas

null;

< 30000;
oficina

Hallar los vendedores que estn debajo de su cuota, pero cuyas ventas no sean inferiores a
150.000.

SELECT nombre

dir

11

106

12

104

13

105

26

NULL

28

NULL

FROM empleados
WHERE ventas < cuota AND ventas

< 150000;

Hallar las oficinas no dirigidas por el empleado 108

SELECT oficina
Lic. Vladimir Cotaquispe Gutirrez. 35

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 36

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

Consultas multitabla
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.

,...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:

Las operaciones de lgebra relacional implementadas en Transact-Sql son:


SELECT oficina as OFI, ciudad FROM Valencia
La unin UNION
UNION ALL
La diferencia EXCEPT

SELECT oficina,

ciudad FROM Madrid;

La interseccin INTERSECT
El producto cartesiano CROSS JOIN

El resultado sera:

La composicin interna INNER JOIN


OFI

ciudad

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 >)}

consulta >|(< consulta >)}

[{UNION
[ORDER

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

UNION [ALL]
{<

11

[ALL] {< consulta >|(< consulta >)}}[ ...n ] ]

SELECT oficina, ciudad FROM Madrid


ORDER BY ofi;

BY {expression_columna|posicion_columna [ASC|DESC]}

Lic. Vladimir Cotaquispe Gutirrez. 37

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 38

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

OFI

ciudad

11

Valencia

23

Madrid

28

Valencia

Power Builder + Sql

WHERE importe > 300;

4.3. La diferencia EXCEPT

Ahora las filas aparecen ordenadas por el nmero de oficina y hemos utilizado el nombre de
columna de la primera consulta.

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>)}
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
El empleo de ALL tambin hace que la consulta se ejecute ms rpidamente ya que el sistema
no tiene que eliminar las repeticiones.

EXCEPT
{<consulta>|(<consulta>)}
[{EXCEPT
[ORDER

{<consulta>|(<consulta>)}}[ ...n ] ]

BY {expression_columna|posicion_columna [ASC|DESC]}

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

,...n ]]

Por ejemplo tenemos las tablas T1 y T2.

UNION

T1

T2

SELECT oficina, ciudad FROM Madrid


UNION

Cod

SELECT oficina, ciudad FROM Pamplona;

Codigo

1
2
2

Combinamos las tres tablas.

3
4
4

Otro ejemplo:
5
Obtener todos los productos cuyo precio exceda de 20 o que se haya vendido ms de 300
euros del producto en algn pedido.

5
6

SELECT idfab, idproducto


SELECT cod FROM T1
FROM

productos
EXCEPT

WHERE precio > 20


SELECT codigo FROM T2;
UNION
SELECT fab, producto

Devuelve:

FROM pedidos
Lic. Vladimir Cotaquispe Gutirrez. 39

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 40

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

Devuelve:

Cod
1

Cod

2
4

Ejemplo:
5
Listar los productos que no aparezcan en ningn pedido.
Ejemplo: Obtener todos los productos que valen ms de 20 euros y que adems se haya
vendido en un pedido ms de 300 euros de ese producto.

SELECT idfab, idproducto


FROM

productos
SELECT idfab, idproducto

EXCEPT
SELECT DISTINCT fab, producto

FROM

productos

WHERE precio > 20

FROM pedidos;

INTERSECT

4.4. La interseccin INTERSECT

SELECT fab, producto


FROM pedidos

Tiene una sintaxis parecida a las anteriores pero en el resultado de la interseccin aparecen
las
filas
que
estn
simultneamente
en
las
dos
consultas.
Las condiciones son las mismas que las de la unin.

WHERE importe > 300;

{ <consulta>|(<consulta>)}

4.5. La composicin de tablas

INTERSECT
{<especificacion_consulta>|(<especificacion_consulta>)}
[{INTERSECT {<consulta>|(<consulta>)}} [ ...n ] ]
[ORDER

BY {expression_columna|posicion_columna [ASC|DESC]}
[

,...n ]]

La sentencia SELECT permite realizar esta composicin, incluyendo dos o ms tablas en la


clusula FROM.

Retomando el ejemplo anterior:

Es hora de ampliar la clusula FROM que vimos en el tema anterior.

SELECT cod FROM T1


INTERSECT

Empezaremos por estudiar la operacin a partir de la cual estn definidas las dems
operaciones de composicin de tabla, el producto cartesiano.

SELECT cod FROM T2;

Lic. Vladimir Cotaquispe Gutirrez. 41

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 cualesquiera 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.

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 42

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

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.

Power Builder + Sql

WHERE empleados.oficina=oficinas.oficina;

Se indica escribiendo en la clusula FROM los nombres de las tablas separados por una
coma o utilizando el operador CROSS JOIN.

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.

FROM {<tabla_origen>} [ ,...n ]

SELECT empleados.*,ciudad, region

|<tabla_origen> CROSS JOIN <tabla_origen>

FROM empleados, oficinas


WHERE empleados.oficina=oficinas.oficina;

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
composicin
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:

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;

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 con 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;

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.

4.7. La composicin interna INNER JOIN


Una composicin interna es aquella en la que los valores de las columnas que se estn
combinando
se
comparan
mediante
un
operador
de
comparacin.
Es otra forma, mejor, de expresar un producto cartesiano con una condicin.
Es la operacin que ms emplearemos ya que lo ms frecuente es querer juntar los registros de
una tabla relacionada con los registros correspondientes en la tabla de referencia (aadir a
cada factura los datos de su cliente, aadir a cada lnea de pedido los datos de su producto,
etc..,).

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:

FROM

SELECT *

tabla_origen tiene el mismo significado que en el producto cartesiano.


condicion_combi es cualquier condicin que permite seleccionar las parejas de filas que
aparecen en el resultado. Normalmente ser una condicin de igualdad.

FROM empleados, oficinas


Lic. Vladimir Cotaquispe Gutirrez. 43

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

<tabla_origen> INNER JOIN <tabla_origen> ON <condicion_combi>

Lic. Vladimir Cotaquispe Gutirrez. 44

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

109

SELECT *

Mara Sunta

11

Valencia

FROM empleados INNER JOIN oficinas


ON

No aparecen los empleados que no tienen oficina, ni las oficinas que no tienen empleados,
porque para que salga la fila, debe de existir una fila de la otra tabla que cumpla la condicin.

empleados.oficina=oficinas.oficina;

externa.

Para resolver este problema debemos utilizar otro tipo de composicin, la composicin

Obtiene los empleados combinados con los datos de su oficina.

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

SELECT *

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.

FROM pedidos INNER JOIN productos


ON producto = idproducto AND fab =

idfab;

Sintaxis
Obtiene los pedidos combinados con los productos correspondientes.
Normalmente la condicin de combinacin ser una igualdad pero se puede utilizar cualquier
operador de comparacin (<>, >).

FROM
<tabla_origen> {LEFT|RIGHT|FULL} [OUTER] JOIN <tabla_origen>

Es fcil ver la utilidad de esta instruccin y de hecho se utilizar muy a menudo, pero hay
algn caso que no resuelve. En las consultas anteriores, no aparecen las filas que no tienen fila
correspondiente en la otra tabla.

SELECT numemp,nombre,empleados.oficina,

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.

ciudad

FROM empleados INNER JOIN oficinas


ON

empleados.oficina=oficinas.oficina;

SELECT numemp,nombre,empleados.oficina,

ciudad

FROM empleados LEFT JOIN oficinas


numemp

nombre

oficina

ciudad

101

Antonio Viguer

12

Alicante

102

Alvaro Jaumes

21

Badajoz

103

Juan Rovira

12

ON

empleados.oficina=oficinas.oficina;

numemp

nombre

oficina

ciudad

101

Antonio Viguer

12

Alicante

Alicante

102

Alvaro Jaumes

21

Badajoz

103

Juan Rovira

12

Alicante

104

Jos Gonzlez

12

Alicante

104

Jos Gonzlez

12

Alicante

105

Vicente Pantalla

13

Castelln

105

Vicente Pantalla

13

Castelln

Valencia

106

Luis Antonio

11

Valencia

107

Jorge Gutirrez

22

A Corua

108

Ana Bustamante

21

Badajoz

109

Mara Sunta

11

Valencia

106

Luis Antonio

11

107

Jorge Gutirrez

22

A Corua

108

Ana Bustamante

21

Badajoz

Lic. Vladimir Cotaquispe Gutirrez. 45

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 46

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

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;

numemp

nombre

oficina

Power Builder + Sql

numemp

ciudad

oficina

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

106

Luis Antonio

11

Valencia

11

NULL

NULL

NULL

Pamplona

26

109

Mara Sunta

11

Valencia

11

NULL

NULL

NULL

Valencia

28

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.

Aparecen tanto los empleados sin oficina como las oficinas sin empleados.

SELECT numemp,nombre,empleados.oficina,

ciudad, oficinas.oficina

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 condicin 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.

SELECT numemp,nombre,empleados.oficina,

ciudad, oficinas.oficina

FROM empleados FULL JOIN oficinas


ON

empleados.oficina=oficinas.oficina;

Lic. Vladimir Cotaquispe Gutirrez. 47

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

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.
Lic. Vladimir Cotaquispe Gutirrez. 48

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

Siguiendo el ejemplo anterior nos preguntaramos:

Consultas de Resumen

Pueden haber empleados que no tengan oficina y nos interesan?, si es que s, necesitamos
un LEFT JOIN.
Seguiramos preguntando:

Una de las funcionalidades de la sentencia SELECT es el permitir obtener resmenes de los


datos contenidos en las columnas de las tablas.

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.

4.9. Combinar varias operaciones


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,
pedidos.*

5.1. Introduccin

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:

nombre,

empleados.oficina,

ciudad,

oficinas.oficina,

FROM (oficinas RIGHT JOIN empleados


ON empleados.oficina = oficinas.oficina)
INNER JOIN pedidos on rep=numemp;

O bien:

SELECT numemp,
pedidos.*

nombre,

empleados.oficina,

ciudad,

oficinas.oficina,

FROM oficinas RIGHT JOIN (empleados INNER JOIN pedidos on rep = numemp)
ON empleados.oficina = oficinas.oficina);

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
valores contenidos en la columna.
Lic. Vladimir Cotaquispe Gutirrez. 49

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 50

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

El mero hecho de utilizar una funcin de agregado en una consulta, convierte sta en una
consulta de resumen.

Power Builder + Sql

SELECT COUNT(region) FROM oficinas;

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
l valor por defecto.
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 ordinarios.
Hay excepciones a esta regla pero cuando definimos agrupaciones y subconsultas que
veremos ms adelante.

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 quedan
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;

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).

5.3. La funcin COUNT


Por ejemplo:
COUNT ({[ALL|DISTINCT] expresion | * } )
SELECT COUNT(*) FROM empleados WHERE oficina IS NOT NULL;
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 int.
Si 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.

Es mejor que:

SELECT COUNT(oficina) FROM empleados WHERE oficina IS NOT NULL;


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.

Las dos nos devuelven el nmero de empleados que tienen una oficina asignada pero la
primera es mejor porque se calcula ms rpidamente.

Por ejemplo:
Lic. Vladimir Cotaquispe Gutirrez. 51

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 52

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

5.4. La funcin COUNT_BIG

Power Builder + Sql

5.7. La funcin SUM

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.

SUM ([ALL|DISTINCT] expresion )

Devuelve la suma de los valores devueltos por la expresin.

5.5. La funcin MAX


Slo puede utilizarse con columnas numricas.
MAX ([ALL|DISTINCT] expression)

El resultado ser del mismo tipo aunque puede tener una precisin mayor.

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.

SELECT SUM(importe) FROM pedidos;

Obtiene el importe total vendido en todos los pedidos.

SELECT SUM(ventas) AS VentasTotales,

MAX(objetivo) AS MayorObjetivo

FROM oficinas;

Por ejemplo:

SELECT SUM(ventas) AS VentasTotales,

MAX(objetivo) AS MayorObjetivo

Devuelve la suma de las ventas de todas las oficinas y de los objetivos de todas las oficinas,
el de mayor importe.

FROM oficinas;

5.8. La funcin AVG


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.

AVG ([ALL|DISTINCT] expresion )

Devuelve el promedio de los valores de un grupo, para calcular el promedio se omiten los
valores nulos.

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.

El grupo de valores 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.
La funcin se aplica tambin a campos numricos, y en este caso el tipo de dato del
resultado puede cambiar segn las necesidades del sistema para representar el valor del
resultado.

5.9. La funcin VAR


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.

Lic. Vladimir Cotaquispe Gutirrez. 53

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

VAR ([ALL|DISTINCT] expresion )

Lic. Vladimir Cotaquispe Gutirrez. 54

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Devuelve la varianza estadstica de todos los valores de la expresin especificada.


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

Power Builder + Sql

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.

5.10. La funcin VARP


VARP ([ALL|DISTINCT] expresion )

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.

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.

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.

5.11. La funcin STDEV


GROUP BY [ ALL ] expresion_agrupacion [ ,...n ]
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.

[ 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 .

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.

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:

En el siguiente punto, cuando veamos las clusulas CUBE y ROLLUP quedar ms claro.
SELECT oficina, count(numemp) AS

[Nmero de empleados]

FROM empleados
Lic. Vladimir Cotaquispe Gutirrez. 55

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 56

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

GROUP BY oficina;

Resultado:
oficina

Nmero de empleados

Power Builder + Sql

103

2111

21,00

105

2103

275,00

105

2111

37,45

106

2101

14,58

NULL

107

2109

313,50

11

107

2124

24,30

12

108

2112

29,25

13

108

2114

71,00

21

108

2118

14,20

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.

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.

Ejemplo:

SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe)


AS [Importe mximo]

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.

FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY

GROUP BY ALL no se admite en consultas que tienen acceso a tablas remotas si tambin
hay una clusula WHERE en la consulta.

rep, clie
Por ejemplo, vamos a modificar la consulta anterior:

ORDER BY rep, clie;


SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe)
AS [Importe mximo]

Resultado:

FROM pedidos
rep

clie

101

2113

Nmero Importe
de pedidos mximo
1
225,00

102

2106

21,30

102

2120

37,50

WHERE YEAR(fechapedido) = 1997


GROUP BY

ALL rep, clie

ORDER BY rep, clie;

Resultado:
Lic. Vladimir Cotaquispe Gutirrez. 57

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 58

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

rep

clie

Power Builder + Sql

Nmero Importe
de pedidos mximo

rep

clie

Nmero Importe
de pedidos mximo

101

2102

NULL

101

2113

225,00

101

2108

NULL

101

NULL

225,00

101

2113

225,00

102

2106

21,30

102

2106

21,30

102

2120

37,50

102

2120

37,50

102

NULL

37,50

103

2111

21,00

103

2111

21,00

105

2103

275,00

103

NULL

21,00

105

2111

37,45

105

2103

275,00

106

2101

14,58

105

2111

37,45

106

2117

NULL

105

NULL

275,00

107

2109

313,50

106

2101

14,28

107

2124

24,30

106

NULL

14,28

108

2112

29,25

107

2109

313,50

108

2114

71,00

107

2124

24,30

108

2118

14,20

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

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.
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]

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.
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:

FROM pedidos
WHERE YEAR(fechapedido) = 1997
GROUP BY

rep, clie WITH ROLLUP;

SELECT rep, clie, count(numpedido) AS [Nmero de pedidos], MAX(importe)


AS [Importe mximo]
FROM pedidos

Resultado:
Lic. Vladimir Cotaquispe Gutirrez. 59

WHERE YEAR(fechapedido) = 1997


E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 60

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

GROUP BY

rep, clie WITH CUBE;

Power Builder + Sql

NULL

2118

14,20

NULL

2120

37,50

NULL

2124

24,30

Resultado:

rep

clie

Nmero Importe
de pedidos mximo

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.

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

FROM pedidos

107

2109

313,50

WHERE YEAR(fechapedido) = 1997

107

2124

24,30

GROUP BY

107

NULL

313,50

108

2112

29,25

108

2114

71,00

108

2118

14,20

101

2113

225,00

108

NULL

71,00

101

NULL

225,00

...

...

...

...

102

2106

21,30

NULL

NULL

23

450,00

102

2120

37,50

NULL

2101

14,58

102

NULL

37,50

NULL

2103

275,00

103

2111

21,00

NULL

2106

21,30

NULL

2107

6,32

NULL

2108

56,25

NULL

2109

313,50

NULL

2111

37,45

NULL

2112

450,00

NULL

2113

225,00

NULL

2114

71,00

Lic. Vladimir Cotaquispe Gutirrez. 61

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

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]

rep

rep, clie WITH ROLLUP;

clie

Nmero Importe
Fila
de pedidos mximo Resumen

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.

Lic. Vladimir Cotaquispe Gutirrez. 62

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

5.15. Seleccin sobre grupos de filas, la clusula HAVING

Power Builder + Sql

HAVING SUM(ventas)=10000

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.

Las Sub consultas


6.1. Introduccin

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]

Una subconsulta es una consulta que aparece dentro de otra consulta o subconsultas, en la
lista de seleccin o en la clusula WHERE o HAVING, originalmente no se podan incluir en la
lista
de
seleccin.
Una subconsulta se denomina tambin consulta o seleccin interna, mientras que la instruccin
que contiene la subconsulta es conocida como consulta o seleccin externa.
Aparece siempre encerrada entre parntesis y tiene la misma sintaxis que una sentencia
SELECT
normal
con
alguna
limitacin:
No puede incluir una clusula COMPUTE o FOR BROWSE y slo puede incluir una clusula
ORDER BY cuando se especifica tambin una clusula TOP.

FROM empleados
Una subconsulta puede anidarse en la clusula WHERE o HAVING de una instruccin
externa SELECT, INSERT, UPDATE o DELETE, o bien en otra subconsulta. Se puede disponer
de hasta 32 niveles de anidamiento, aunque el lmite vara dependiendo de la memoria
disponible y de la complejidad del resto de las expresiones de la consulta. Hay que tener en
cuenta que para cada fila de la consulta externa, se calcula la subconsulta, si anidamos varias
consultas, el nmero de veces que se ejecutarn las subconsultas puede dispararse!

GROUP BY oficina
HAVING COUNT(numemp)<2;

Resultado:
Cuando la subconsulta aparece en la lista de seleccin de otra consulta, deber devolver un
solo valor, de lo contrario provocar un error.

oficina Nmero de empleados


13

22

Ejemplo de subconsulta: Listar los empleados cuya cuota no supere el importe vendido por
el empleado.

SELECT nombre
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:
Lic. Vladimir Cotaquispe Gutirrez. 63

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

FROM empleados
WHERE cuota <= (SELECT SUM(importe)
FROM pedidos
WHERE rep = numemp);

Por cada fila de la tabla de empleados (de la consulta externa) se calcula la subconsulta y se
evala la condicin, por lo que utilizar una subconsulta puede en algunos casos ralentizar la
consulta, en contrapartida se necesita menos memoria que una composicin de tablas.
Muchas de las instrucciones Transact-SQL que incluyen subconsultas se pueden formular
tambin utilizando composiciones de tablas. Otras preguntas se pueden formular slo con
subconsultas.
Lic. Vladimir Cotaquispe Gutirrez. 64

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

En Transact-SQL, normalmente no hay una regla fija en cuanto a diferencias de rendimiento


entre una instruccin que incluya una subconsulta y una versin semnticamente equivalente
que no la incluya.
Podremos utilizar una subconsulta siempre y cuando no se quiera que aparezcan en el
resultado columnas de la subconsulta ya que si una tabla aparece en la subconsulta y no en la
consulta externa, las columnas de esa tabla no se pueden incluir en la salida (la lista de
seleccin de la consulta externa).

Power Builder + Sql

SELECT oficina, ciudad


FROM oficinas
WHERE objetivo > (SELECT SUM(ventas)
FROM empleados
WHERE oficina = oficina);

Tenemos tres tipos de subconsultas:


Las que devuelven un solo valor, aparecen en la lista de seleccin de la consulta externa
o con un operador de comparacin sin modificar.
Las que generan una columna de valores, aparecen con el operador IN o con
un operador de comparacin modificado con ANY, SOME o ALL.
Las que pueden generar cualquier nmero de columnas y filas, son utilizadas en pruebas
de existencia especificadas con EXISTS.
A lo largo del tema las estudiaremos todas.
Antes de terminar con la introduccin queda comentar el concepto de referencia externa muy
til en las subconsultas.

La columna oficina se encuentra en los dos orgenes (oficinas y empleados) pero esta
consulta no dar error (no se nos pedir cualificar los nombres como pasara en una
composicin de tablas), dentro de la subconsulta se considera oficina el campo de la tabla
empleados. Con lo que comparara la oficina del empleado con la misma oficina del empleado y
eso no es lo que queremos, queremos comparar la oficina del empleado con la oficina de
oficinas, lo escribiremos pues as para forzar a que busque la columna en la tabla oficinas.

SELECT oficina, ciudad


FROM oficinas
WHERE objetivo > (SELECT SUM(ventas)
FROM empleados

A menudo, es necesario, dentro del cuerpo de una subconsulta, hacer referencia al valor de
una columna en la fila actual de la consulta externa, el nombre de columna de la consulta
externa dentro de la subconsulta recibe el nombre de referencia externa, ya que hace referencia
a una columna externa.
En el ejemplo anterior numemp es una referencia externa, no es una columna del origen de
datos de la subconsulta (pedidos), es una columna del origen de la consulta externa
(empleados).
Hay que tener en cuenta de cmo se ejecuta la consulta; por cada fila de la consulta externa
se calcula el resultado de la subconsulta y se evala la comparacin.
En el ejemplo, se coge el primer empleado (numemp= 101, por ejemplo) y se calcula la
subconsulta sustituyendo numemp por el valor 101, se calcula la suma de los pedidos del rep =
101, y el resultado se compara con la cuota de ese empleado, y as se repite el proceso con
todas las filas de empleados.
El nombre de una columna dentro de la subconsulta se presupone del origen de datos de la
subconsulta y, slo si no se encuentra en ese origen, la considera como columna externa y la
busca en el origen de la consulta externa.

WHERE oficina = oficinas.oficina);

6.2. Subconsultas de resultado nico


Existen subconsultas que deben obligatoriamente devolver un nico valor, son las que
aparecen en la lista de seleccin de la consulta externa o las que aparecen en WHERE o
HAVING combinadas con un operador de comparacin sin modificar.
Los operadores de comparacin sin modificar son los operadores de comparacin que vimos
con la clusula WHERE.
Sintaxis:

<expresion>

{=|<>|!=|>|>=|!>|<|<=|!<} <subconsulta>

En este caso la segunda expresin ser una subconsulta, con una sola columna en la lista
de seleccin y deber devolver una nica fila como mucho.
Por ejemplo:
Ese valor nico ser el que se compare con el resultado de la primera expresin.
Lic. Vladimir Cotaquispe Gutirrez. 65

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 66

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

Si la subconsulta no devuelve ninguna fila, la comparacin opera como si la segunda


expresin fuese nula.

WHERE region = 'Este');

Si la subconsulta devuelve ms de una fila o ms de una columna, da error.


Por cada empleado se calcula la lista de las oficinas del Este (n de oficina) y se evala si la
oficina del empleado est en esta lista. Obtenemos pues los empleados de oficinas del Este.

Ejemplo:

numemp

nombre

edad oficina

titulo

contrato

jefe

cuota

ventas

104

30000,00

30500,00

104

27500,00

28600,00

106

20000,00

14300,00

104

35000,00

36800,00

NULL

27500,00

29900,00

SELECT nombre
101
FROM empleados
103

WHERE cuota <= (SELECT SUM(importe)


FROM pedidos

104

WHERE rep = numemp);

105
106

La subconsulta devuelve una sola columna y como mucho una fila ya que es una consulta
de resumen sin clusula GROUP BY.

Antonio
Viguer
Juan
Rovira
Jos
Gonzlez
Vicente
Pantalla
Luis
Antonio

45

12

representante

29

23

representante

33

23

dir ventas

37

13

representante

52

11

dir general

198610-20
198703-01
198705-19
198802-12
198806-14

Si la subconsulta no devuelve ninguna fila:

6.3. Subconsultas de lista de valores


SELECT *
Otro tipo de subconsultas son las que devuelven una lista de valores en forma de una
columna y cero, una o varias filas.
Estas consultas aparecen en las clusulas WHERE o HAVING combinadas con el operador
IN o con comparaciones modificadas.

FROM empleados
WHERE oficina IN (SELECT oficina
FROM oficinas
WHERE region = 'Otro');

6.4. El operador IN con subconsulta

La lista generada est vaca por lo que la condicin IN devuelve FALSE y en este caso no
sale ningn empleado.

<expresion> IN subconsulta

IN examina si el valor de expresion es uno de los valores incluidos en la lista de valores


generados por la subconsulta.

Muchas veces la misma pregunta se puede resolver mediante una composicin de tablas.

La subconsulta tiene que generar valores de un tipo compatible con la expresin.

SELECT empleados.*

Ejemplo:

FROM
Empleados
oficinas.oficina

INNER

JOIN

oficinas

ON

empleados.oficina

WHERE region = 'Este';


SELECT *
FROM empleados

Esta sentencia es equivalente. En el resultado no queremos ver ninguna columna de la tabla


oficinas, el JOIN lo tenemos slo para la pregunta, en este caso pues se puede sustituir por una
subconsulta.

WHERE oficina IN (SELECT oficina


FROM oficinas
Lic. Vladimir Cotaquispe Gutirrez. 67

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 68

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

SELECT *
Si combinamos el operador IN con NOT obtenemos el operador NOT IN.

FROM Oficinas
WHERE oficina NOT IN (SELECT oficina

<expresion> NOT IN subconsulta


FROM empleados);
Devuelve TRUE si el valor de la expresin no est en la lista de valores devueltos por la
subconsulta.

SELECT *

Esta consulta no devuelve ninguna fila cuando s debera ya que hay oficinas que nos estn
asignadas a ningn empleado. El problema est en que la columna oficina de la tabla
empleados admite nulos por lo que la subconsulta devuelve valores nulos en todos los
empleados que no estn asignados a ninguna oficina. Estos valores nulos hacen que no se
cumpla el NOT IN. La solucin pasa por eliminar estos valores molestos:

FROM empleados
WHERE oficina NOT IN (SELECT oficina

SELECT *
FROM oficinas

FROM Oficinas

WHERE region = 'Este');

WHERE oficina NOT IN (SELECT oficina


FROM empleados

Devuelve los empleados cuya oficina no est en la lista generada por la subconsulta, es
decir empleados que trabajan en oficinas que no son del Este.
OJO con NOT IN.
Hay que tener especial cuidado con los valores nulos cuando utilizamos el operador NOT IN
porque el resultado obtenido no siempre ser el deseado por ejemplo:
* En la consulta anterior no salen los empleados que no tienen oficina ya que para esos
empleados la columna oficina contiene NULL por lo que no se cumple el NOT IN.
* Si la subconsulta no devuelve ninguna fila, la condicin se cumplir para todas las filas de
la consulta externa, en este caso todos los empleados.

WHERE oficina IS NOT NULL);

En el primer ejemplo no tenemos ese problema porque la columna oficina en oficinas no


admite nulos.
A diferencia de IN, NOT IN no siempre puede resolverse con una composicin:

SELECT numemp AS [IN]


FROM empleados
WHERE numemp IN (SELECT rep

* Si la subconsulta devuelve algn valor NULL, la condicin NOT IN es NULL lo que nos
puede ocasionar algn problema.

FROM pedidos
WHERE fab = 'ACI');

Por ejemplo, queremos obtener las oficinas que no estn asignadas a ningn empleado.
Se puede resolver con una composicin:

SELECT DISTINCT empleados.numemp AS [=]


FROM Empleados INNER JOIN pedidos ON numemp = rep
WHERE fab = 'ACI';

Lic. Vladimir Cotaquispe Gutirrez. 69

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 70

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

Power Builder + Sql

En este caso, como un empleado puede tener varios pedidos hay que aadir DISTINCT para
eliminar las repeticiones de empleados (si un empleado tiene varios pedidos de ACI aparecera
varias veces).

ANY significa que, para que una fila de la consulta externa satisfaga la condicin
especificada, la comparacin se debe cumplir para al menos un valor de los devueltos por la
subconsulta.

Sin embargo esta sentencia con NOT IN, queremos los empleados que no tienen pedidos de
ACI:

Por cada fila de la consulta externa se evala la comparacin con cada uno de los valores
devueltos por la subconsulta y si la comparacin es True para alguno de los valores ANY es
verdadero, si la comparacin no se cumple con ninguno de los valores de la consulta, ANY da
False a no ser que todos los valores devueltos por la subconsulta sean nulos en tal caso ANY
dar
NULL.
Si la subconsulta no devuelve filas ANY da False incluso si expresion es nula.

SELECT numemp AS [NOT IN]


Ejemplo:
FROM empleados
WHERE numemp NOT IN (SELECT rep

SELECT *
FROM pedidos

FROM empleados

WHERE fab = 'ACI');

WHERE cuota > ANY (SELECT cuota


FROM empleados empleados2

No se puede resolver con una composicin:


WHERE

empleados.oficina

empleados2.oficina);
SELECT DISTINCT empleados.numemp AS [<>]
FROM Empleados INNER JOIN pedidos ON numemp = rep
WHERE fab <> 'ACI';

Esta consulta devuelve los empleados que tienen pedidos que no son de ACI, pero un
empleado puede tener pedidos de ACI y otros de otros fabricantes y por estos otros saldra en
el
resultado
cuando
s
tiene
pedidos
de
ACI
y
no
debera
salir.
Hay que tener mucho cuidado con este tipo de preguntas.

Obtenemos los empleados que tienen una cuota superior a la cuota de alguno de sus
compaeros de oficina, es decir los empleados que no tengan la menor cuota de su oficina.
En este caso hemos tenido un alias de tabla en la subconsulta (empleados2) para poder
utilizar una referencia externa.
El test ALL
<expresion>

{=|<>|!=|>|>=|!>|<|<=|!<} ALL subconsulta

6.5. La comparacin modificada (ANY, ALL)


Los operadores de comparacin que presentan una subconsulta se pueden modificar
mediante las palabras clave ALL, ANY o SOME. SOME es un equivalente del estndar de SQL92 de ANY.

Con el modificador ALL, para que se cumpla la condicin, la comparacin se debe cumplir
con cada uno de los valores devueltos por la subconsulta.
Si la subconsulta no devuelve ninguna fila ALL da True.

Se utiliza este tipo de comparacin cuando queremos comparar el resultado de la expresin


con una lista de valores y actuar en funcin del modificador empleado.
El test ANY
<expresion>

SELECT *
{=|<>|!=|>|>=|!>|<|<=|!<} {ANY|SOME} subconsulta

FROM empleados
WHERE cuota > ALL (SELECT cuota
FROM empleados empleados2

Lic. Vladimir Cotaquispe Gutirrez. 71

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Lic. Vladimir Cotaquispe Gutirrez. 72

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

WHERE

empleados.oficina

Power Builder + Sql

empleados2.oficina);

No se realiza ninguna comparacin con los valores devueltos por la subconsulta,


simplemente se evala si la subconsulta devuelve alguna fila, en este caso EXISTS ser True y
si la subconsulta no devuelve ninguna fila, EXISTS ser False.
Ejemplo:

En el ejemplo anterior obtenemos los empleados que tengan una cuota superior a todas las
cuotas de la oficina del empleado. Podramos pensar que obtenemos el empleado de mayor
cuota de su oficina pero no lo es, aqu tenemos un problema, la cuota del empleado aparece en
el resultado de subconsulta por lo tanto > no se cumplir para todos los valores y slo saldrn
los empleados que no tengan oficina (para los que la subconsulta no devuelve filas).
Para salvar el problema tendramos que quitar del resultado de la subconsulta la cuota del
empleado modificando el WHERE:

SELECT *
FROM empleados
WHERE EXISTS (SELECT *
FROM pedidos
WHERE numemp = rep and fab ='ACI');

WHERE empleados.oficina = empleados2.oficina


AND empleados.numemp <> empleados2.numemp);

De esta forma saldran los empleados que tienen una cuota mayor que cualquier otro
empleado de su misma oficina.
O bien

WHERE empleados.oficina = empleados2.oficina


AND empleados.cuota <> empleados2.cuota);

Obtenemos los empleados que tengan un pedido del fabricante ACI. Por cada empleado, se
calcula la subconsulta (obteniendo los pedidos de ese empleado y con fabricante ACI), si existe
alguna fila, el empleado sale en el resultado, si no, no sale.
Cuando se utiliza el operador EXISTS es muy importante aadir una referencia externa, no
es obligatorio pero en la mayora de los casos ser necesario. Vemoslo con ese mismo
ejemplo, si quitamos la referencia externa:

SELECT *
FROM empleados
WHERE EXISTS (SELECT *

Para no considerar los empleados que tengan la misma cuota que el empleado. En este
caso saldran los empleados con la mayor cuota de sus oficina, pero si dos empleados tienen la
misma cuota superior, saldran, hecho que no sucedera con la otra versin.
Cuando la comparacin es una igualdad, = ANY es equivalente a IN y <> ALL es equivalente
a NOT IN (con los mismos problemas).

6.6. Subconsultas con cualquier nmero de columnas (EXISTS)


Existe otro operador de subconsulta con el que la subconsulta puede devolver ms de una
columna,
el
operador
EXISTS.
En este caso la sintaxis es algo diferente:

FROM pedidos
WHERE fab ='ACI');

Sea el empleado que sea, la subconsulta siempre devolver filas (si existe algn pedido
cuyo fabricante sea ACI) o nunca, indistintamente del empleado que sea, por lo que se
obtendrn todos los empleados o ninguno para que el resultado vare segn las filas de la
consulta externa habr que incluir una referencia externa.
Otra cosa a tener en cuenta es que la lista de seleccin de una subconsulta que se
especifica con EXISTS casi siempre consta de un asterisco (*). No hay razn para enumerar los
nombres de las columnas porque no se van a utilizar y supone un trabajo extra para el sistema.
Si utilizamos NOT EXISTS el resultado ser el contrario.

SELECT *
WHERE [NOT] EXISTS subconsulta
Lic. Vladimir Cotaquispe Gutirrez. 73

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

FROM empleados
Lic. Vladimir Cotaquispe Gutirrez. 74

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

Power Builder + Sql

WHERE NOT EXISTS (SELECT *


FROM pedidos
WHERE fab ='ACI' AND rep=numemp);

Devuelve los empleados que no tienen ningn pedido de ACI.

Lic. Vladimir Cotaquispe Gutirrez. 75

E.P. DE INGENIERIA DE SISTEMA E INFORMATICA

You might also like