Sei sulla pagina 1di 34

UNDAC SBD I

Ing. Williams A. Muoz Robles 1


Insertar datos en Transact SQL
Insercin individual de filas.
Para realizar la insercin individual de filas SQL posee la instruccin INSERT INTO. La
insercin individual de filas es la que ms comnmente utilizaremos. Su sintaxis es la
siguiente:
INSERT INTO <nombre_tabla>
[(<campo1>[,<campo2>,...])]
values
(<valor1>,<valor2>,...);
El siguiente ejemplo muestra la insercin de un registro en la tabla PRECIOS.
INSERT INTO PRECIOS
(PRECIO, FX_INICIO, FX_FIN, CO_PRODUCTO)
VALUES
(10, getdate(),getdate()+30, 1)
Insercin mltiple de filas.
Tambin es posible insertar en una tabla el resultado de una consulta SELECT. De
este modo se insertarn tantas filas como haya devuelto la consulta SELECT.
El siguiente ejemplo muestra la insercin multiple de filas.
INSERT INTO PRECIOS
(PRECIO, FX_INICIO, FX_FIN, CO_PRODUCTO)
SELECT PRECIO_UNIDAD, getdate(), getdate() + 30, CO_PRODUCTO
FROM DETALLE_PEDIDO
UNDAC SBD I
Ing. Williams A. Muoz Robles 2
Insercin de valores por defecto.
Tambin podemos forzar a que la inserccin se realice con los datos por defecto
establecidos para la tabla (o null si no tienen valores por defecto).
INSERT INTO PRECIOS DEFAULT VALUES
En SQL Sever podemos marcar un campo de una tabla como autonumrico (identity),
cuando insertamos un registro en dicha tabla el valor del campo se genera
automaticamente. Para recuperar el valor generado disponemos de varios mtodos:
Utilizar la funcion @@identity, que devuelve el ltimo valor identidad insertado por la
transaccion:
DECLARE @Codigo int
INSERT INTO PRECIOS
(PRECIO, FX_INICIO, FX_FIN, CO_PRODUCTO)
VALUES
(10, getdate(),getdate()+30, 1)
set @Codigo = @@Identity
PRINT @Codigo
El uso de @@Identity no siempre es vlido, ya que al devolver el litmo valor
identidad insertado por la transaccin, no nos garantiza que el valor haya sido
insertado en la tabla que nos interesa (por ejemplo la tabla podra tener un trigger que
insertara datos en otra tabla con campos identidad).
En este tipo de escenarios debemos utilizar la funcin, SCOPE_IDENTITY.
DECLARE @Codigo int
UNDAC SBD I
Ing. Williams A. Muoz Robles 3
INSERT INTO PRECIOS
(PRECIO, FX_INICIO, FX_FIN, CO_PRODUCTO)
VALUES
(10, getdate(),getdate()+30, 1)
SET @Codigo = SCOPE_IDENTITY()
PRINT @Codigo
Clausula OUTPUT
A partir de la versin de SQL Server 2005 disponemos de la clausula OUTPUT para
recuperar los valores que hemos insertado. Al igual que en un trigger disponemos de
las tablas lgicas INSERTEDy DELETED.
Las columnas con prefijo DELETED reflejan el valor antes de que se complete la
instruccin UPDATE o DELETE. Es decir, son una copia de los datos "antes" del
cambio.
DELETED no se puede utilizar con la clusula OUTPUT en la instruccin INSERT.
Las columnas con prefijo INSERTED reflejan el valor despus de que se complete la
instruccin UPDATE o INSERT, pero antes de que se ejecuten los desencadenadores.
Es decir, son una copia de los datos "despues" del cambio.
INSERTEDno se puede utilizar con la clusula OUTPUT en la instruccin DELETE.
DECLARE @FILAS_INSERTADAS TABLE
( CO_PRECIO int,
PRECIO decimal,
FX_INICIO datetime,
FX_FIN datetime,
CO_PRODUCTO int
)
INSERT INTO PRECIOS
(PRECIO, FX_INICIO, FX_FIN, CO_PRODUCTO)
UNDAC SBD I
Ing. Williams A. Muoz Robles 4
OUTPUT INSERTED.* INTO @FILAS_INSERTADAS
VALUES
(10, getdate(),getdate()+30, 1)
SELECT * FROM @FILAS_INSERTADAS
UNDAC SBD I
Ing. Williams A. Muoz Robles 5
Actualizar datos en Transact SQL
Update
Para la actualizacin de datos Transact SQL dispone de la sentencia UPDATE. La
sentencia UPDATE permite la actualizacin de uno o varios registros de una nica
tabla. La sintaxis de la sentencia UPDATE es la siguiente
UPDATE <nombre_tabla>
SET <campo1> = <valor1>
{[,<campo2> = <valor2>,...,<campoN> = <valorN>]}
[ WHERE <condicion>];
El siguiente ejemplo muestra el uso de UPDATE.
UPDATE CLIENTES
SET
NOMBRE = 'Devjoker',
APELLIDO1 = 'Herrarte',
APELLIDO2 = 'Snchez'
WHERE CO_CLIENTE = 10
Un aspecto a tener en cuenta, sobre todo si has trabajado con ORACLE, es que SQL
graba los cambios inmediatamente sin necesidad de hacer COMMIT. Por supuesto
podemos gestionar nosostros las transacciones pero es algo que hay que hacer de
forma explicita con la instruccion BEGIN TRANy que se ver en capitulos posteriores
de este tutorial.
Update INNER J OIN
En ocasiones queremos actualizar los datos de una tabla con los datos de otra (muy
comn para desnormalizar un modelo de datos).
UNDAC SBD I
Ing. Williams A. Muoz Robles 6
Habitualmente, usamos subconsultas para este proposito, pero Transact SQL permite
la utilizacin de la sentencia UPDATE INNER J OIN.
UPDATE CLIENTES
SET
NOMBRE = FICHERO_CLIENTES.NOMBRE,
APELLIDO1 = FICHERO_CLIENTES.APELLIDO1,
APELLIDO2 = FICHERO_CLIENTES.APELLIDO2
FROM CLIENTES
INNER JOIN FICHERO_CLIENTES
ON FICHERO_CLIENTES.CO_CLIENTE = CLIENTES.CO_CLIENTE
Clausula OUTPUT
A partir de la version de SQL Server 2005 disponemos de la clausula OUTPUT para
recuperar los valores que hemos insertado. Al igual que en un trigger disponemos de
las tablas lgicas INSERTED y DELETED.
Las columnas con prefijo DELETED reflejan el valor antes de que se complete la
instruccin UPDATE o DELETE. Es decir, son una copia de los datos "antes" del
cambio.
DELETED no se puede utilizar con la clusula OUTPUT en la instruccin INSERT.
DECLARE @FILAS_ACTUALIZADAS TABLE
( CO_CLIENTE int ,
NOMBRE varchar(100),
APELLIDO1 varchar(100),
APELLIDO2 varchar(100)
)
UNDAC SBD I
Ing. Williams A. Muoz Robles 7
UPDATE CLIENTES
SET
NOMBRE = 'Devjoker',
APELLIDO1 = 'Herrarte',
APELLIDO2 = 'Snchez'
OUTPUT DELETED.* INTO @FILAS_ACTUALIZADAS
WHERE CO_CLIENTE IN (10, 11, 12)
SELECT * FROM @FILAS_ACTUALIZADAS
Las columnas con prefijo INSERTED reflejan el valor despus de que se complete la
instruccin UPDATE o INSERT, pero antes de que se ejecuten los desencadenadores.
Es decir, son una copia de los datos "despus" del cambio.
INSERTEDno se puede utilizar con la clusula OUTPUT en la instruccin DELETE.
DECLARE @FILAS_ACTUALIZADAS TABLE
( CO_CLIENTE int ,
NOMBRE varchar(100),
APELLIDO1 varchar(100),
APELLIDO2 varchar(100)
)
UPDATE CLIENTES
SET
NOMBRE = 'Devjoker',
APELLIDO1 = 'Herrarte',
APELLIDO2 = 'Snchez'
OUTPUT INSERTED.* INTO @FILAS_ACTUALIZADAS
WHERE CO_CLIENTE IN (10, 11, 12)
SELECT * FROM @FILAS_ACTUALIZADAS
UNDAC SBD I
Ing. Williams A. Muoz Robles 8
Borrar datos en Transact SQL
Delete
Para borrar datos de una tabla debemos utilizar la sentencia DELETE.
Para ejecutar los ejemplos de este apartado debemos ejecutar el siguiente script, que
crea la tabla "DATOS" y carga registros en ella.
CREATE TABLE DATOS
(
Id int identity not null,
dato varchar(100),
fx_alta datetime,
constraint PK_DATOS PRIMARY KEY (Id)
)
GO
DECLARE @i int, @dato varchar(100)
set @i = 0
WHILE (@i <100)
BEGIN
SET @i = @i +1
set @dato = 'Dato:' + cast(@i as varchar)
INSERT INTO DATOS (dato, fx_alta)
VALUES (@dato, getdate())
END
GO
SELECT * from DATOS
Para borrar los registros de la tabla "DATOS" ejecutaremos la siguiente instruccin.
Notese que no se especifica ninguna condicin WHERE por lo que se borran todos los
datos de la tabla.
UNDAC SBD I
Ing. Williams A. Muoz Robles 9
DELETE
FROM DATOS
Lgicamente podemos especicar que registros queremos borrar a travs de la clausula
WHERE.
DELETE
FROM DATOS
WHERE Id=12
Cuando borramos datos de una tabla, podemos obtener el nmero de filas que han
sido afectadas por la instruccin a travs de la variable @@RowCount.
El siguiente ejemplo ilustra el uso de @@RowCount.
DELETE
FROM DATOS
WHERE Id=17
SELECT @@ROWCOUNT
Clausula OUTPUT
A partir de la version de SQL Server 2005 disponemos de la clausula OUTPUT para
recuperar los valores que hemos insertado. Al igual que en un trigger disponemos de
las tablas lgicas INSERTED y DELETED.
Las columnas con prefijo DELETED reflejan el valor antes de que se complete la
instruccin UPDATE o DELETE. Es decir, son una copia de los datos "antes" del
cambio.
DELETED no se puede utilizar con la clusula OUTPUT en la instruccin INSERT.
UNDAC SBD I
Ing. Williams A. Muoz Robles 10
DECLARE @FILAS_BORRADAS TABLE
(
Id int,
dato varchar(100),
fx_alta datetime
)
DELETE
FROM DATOS
OUTPUT DELETED.* INTO @FILAS_BORRADAS
WHERE Id=17
SELECT * from @FILAS_BORRADAS
Truncate Table
Para borrar datos de forma masiva disponemos de la instruccin TRUNCATE TABLE,
que borra todos los datos de una tabla.
TRUNCATE TABLE DATOS
Cuando trabajamos con TRUNCATE TABLE debemos tener en cuenta las siguientes
consideraciones:
TRUNCATE TABLE no admite la clausula WHERE.
No podemos ejecutar TRUNCATE TABLE sobre tablas que sean "padres" en foreign
keys.
UNDAC SBD I
Ing. Williams A. Muoz Robles 11
Consultar datos en Transact SQL
SENTENCI A SELECT
La sentencia SELECT nos permite consultar los datos almacenados en una tabla de la
base de datos.
El formato de la sentencia select es:
SELECT [ALL | DISTINCT ][ TOP expression [ PERCENT ] [
WITH TIES ] ]
<nombre_campos>
FROM <nombre_tabla>
[ INNER | LEFT [OUTER]| RIGHT [OUTER] | CROSS]
[JOIN ] <nombre_tabla> ON <condicion_join>[ AND|OR
<condicion>]
[WHERE <condicion> [ AND|OR <condicion>]]
[GROUP BY <nombre_campos>]
[HAVING <condicion>[ AND|OR <condicion>]]
[ORDER BY <nombre_campo> [ASC | DESC]
El siguiente ejemplo muestra una consulta sencilla que obtiene el cdigo y la "familia"
de una tabla llamada familias (representara familias de productos por ejemplo).
SELECT CO_FAMILIA, FAMILIA
FROM FAMILIAS
El uso del asterisco indica que queremos que la consulta devuelva todos los campos
que existen en la tabla.
SELECT *
FROM FAMILIAS
UNDAC SBD I
Ing. Williams A. Muoz Robles 12
Ahora vamos a realizar una consulta obteniendo adems de los datos de familias, los
datos de las categorias y los productos.
SELECT *
FROM FAMILIAS
INNER JOIN CATEGORIAS
ON CATEGORIAS.CO_FAMILIA = FAMILIAS.CO_FAMILIA
INNER JOIN PRODUCTOS
ON PRODUCTOS.CO_CATEGORIA = CATEGORIAS.CO_CATEGORIA
La combinacin se realiza a travs de la clausula INNER J OI N, que es una clasula
exclusiva, es decir las familias que no tengan categorias y productos asociados no se
devolveran.
Si queremos realizar la consulta para que no sea exclusiva, tenemos que utilizar LEFT
J OIN. El uso de la palabra reservada OUTER es opcional.
SELECT *
FROM FAMILIAS
LEFT OUTER JOIN CATEGORIAS
ON CATEGORIAS.CO_FAMILIA = FAMILIAS.CO_FAMILIA
LEFT OUTER JOIN PRODUCTOS
ON PRODUCTOS.CO_CATEGORIA = CATEGORIAS.CO_CATEGORIA
Los registros que no tengan datos relacionados en una consulta LEFT J OIN
devolveran en valor null en los campos que correspondan a las tablas en las que no
tienen dato.
Tambin podemos forzar un producto cartesiano (todos con todos) a travs de CROSS
J OIN.
SELECT * FROM FAMILIAS
CROSS JOIN CATEGORIAS
UNDAC SBD I
Ing. Williams A. Muoz Robles 13
La clusula WHERE
La clusula WHERE es la instruccin que nos permite filtrar el resultado de una
sentencia SELECT.
SELECT CO_FAMILIA, FAMILIA
FROM FAMILIAS
WHERE CO_FAMILIA = 1
Por supuesto, podemos especificar varias condiciones para el WHERE:
SELECT *
FROM FAMILIAS
WHERE CO_FAMILIA = 1
OR CO_FAMILIA = 2
Podemos agrupar varias valores para una condicion en la clausula IN:
SELECT *
FROM FAMILIAS
WHERE CO_FAMILIA IN ( 1 , 2)
La clausula WHERE se puede utilizar conjuntamente con INNER J OIN, LEFT J OIN
...
SELECT FAMILIAS.CO_FAMILIA,
FAMILIAS.FAMILIA
FROM FAMILIAS
INNER JOIN CATEGORIAS
ON CATEGORIAS.CO_FAMILIA = FAMILIAS.CO_FAMILIA
WHERE FAMILIAS.CO_FAMILIA > 1
UNDAC SBD I
Ing. Williams A. Muoz Robles 14
Siempre que incluyamos un valor alfanumerico para un campo en la condicin WHERE
este debe ir entre comillas simples:
SELECT *
FROM FAMILIAS
WHERE FAMILIA = 'FAMILIA 1'
Para consultar campos alfanumericos, es decir, campos de texto podemos utilizar el
operador LIKE conjuntamente con comodines.
SELECT *
FROM FAMILIAS
WHERE FAMILIA LIKE 'FAM%'
Los comodines que podemos utilizar en son los siguientes:
% , representa cualquier cadena de texto de cero o ms caracteres de cualquier longitud.
_ , representa un carcter.
[a-d], representa cualquier carcter del intervalo a-d.
[abcd], representa cualquier carcter del grupo abcd.
[^a-d], representa cualquier carcter diferente del intervalo a-d.
[^abcd], representa cualquier carcter distinto del grupo abcd.
Tambin podemos obtener los valores distintos utilizando DISTINCT.
SELECT DISTINCT FAMILIA -- Devuelve los distintos valores de FAMILIA
FROM FAMILIAS
Podemos limitar el nmero de registros que devuelve la consulta a travs de la
clausula TOP. La clausula TOP admite como parmetros un valor numrico entero o
un porcentaje (slo a partir de la version 2005)
UNDAC SBD I
Ing. Williams A. Muoz Robles 15
SELECT TOP 10 * -- Devuelve 10 registros
FROM FAMILIAS
SELECT TOP 50 PERCENT * -- Devuelve el 50% de los registros
FROM FAMILIAS
La clausula TOPse puede combinar con WITH TIES en consultas agregadas.
La clusula ORDER BY
Podemos especificar el orden en el que sern devueltos los datos a travs de la
clusula ORDER BY.
SELECT CO_FAMILIA, FAMILIA
FROM FAMILIAS
ORDER BY FAMILIA DESC
Tambin podemos indicar el ndice del campo en la lista de seleccin en lugar de su
nombre:
SELECT CO_FAMILIA, FAMILIA
FROM FAMILIAS
ORDER BY 2 DESC -- Ordena por FAMILIA
UNDAC SBD I
Ing. Williams A. Muoz Robles 16
Consultas agregadas
La clusula GROUP BY
La clausula GROUP BY combina los registros devueltos por una consulta SELECT
obteniendo uno o varios valores agregados(suma, valor mnimo y mximo ...).
Para cada registro se puede crear un valor agregado si se incluye una funcin SQL
agregada, como por ejemplo Sum o Count, en la instruccin SELECT. Su sintaxis es:
SELECT [ALL | DISTINCT ] [TOP <n> [WITH TIES]]
<nombre_campo> [{,<nombre_campo>}]
[{,<funcion_agregado>}]
FROM <nombre_tabla>|<nombre_vista>
[{,<nombre_tabla>|<nombre_vista>}]
[WHERE <condicion> [{ AND|OR <condicion>}]]
[GROUP BY <nombre_campo> [{,<nombre_campo >}]]
[HAVING <condicion>[{ AND|OR <condicion>}]]
[ORDER BY <nombre_campo>|<indice_campo> [ASC | DESC]
[{,<nombre_campo>|<indice_campo> [ASC | DESC ]}]]
Si se utiliza GROUP BY pero no existe una funcin SQL agregada en la instruccin
SELECT se obtiene el mismo resultado que con una consulta SELECT DISTINCT. Los
valores Null en los campos GROUP BY se agrupan y no se omiten. No obstante, los
valores Null no se evalan en ninguna de las funciones SQL agregadas.
Todos los campos de la lista de campos de SELECT deben incluirse en la clusula
GROUP BY o como argumentos de una funcin SQL agregada.
El siguiente ejemplo realiza una "cuenta" de los datos que hay en la tabla
PRODUCTOS.
UNDAC SBD I
Ing. Williams A. Muoz Robles 17
SELECT COUNT(*)
FROM PRODUCTOS
Este otro ejemplo, muestra la suma del PRECIO de cada uno de los productos que
componen un pedido, para calcular el total del pedido agrupados por los datos del
cliente.
SELECT CLIENTES.NOMBRE,
CLIENTES.APELLIDO1,
CLIENTES.APELLIDO2,
SUM(PRECIO) -- Total del pedido
FROM DETALLE_PEDIDO
INNER JOIN PEDIDOS
ON DETALLE_PEDIDO.CO_PEDIDO = PEDIDOS.CO_PEDIDO
INNER JOIN CLIENTES
ON PEDIDOS.CO_CLIENTE = CLIENTES.CO_CLIENTE
GROUP BY CLIENTES.NOMBRE,
CLIENTES.APELLIDO1,
CLIENTES.APELLIDO2
Siempre que incluyamos una clausula WHERE en una consulta agregada esta se aplica
antes de calcular el valor agregado. Es decir, si sumamos el valor de las ventas por
producto, la suma se calcula despues de haber aplicado el filtro impuesto por la
clausula WHERE.
SELECT CLIENTES.NOMBRE,
CLIENTES.APELLIDO1,
CLIENTES.APELLIDO2,
SUM(PRECIO) -- Total del pedido
FROM DETALLE_PEDIDO
INNER JOIN PEDIDOS
ON DETALLE_PEDIDO.CO_PEDIDO = PEDIDOS.CO_PEDIDO
INNER JOIN CLIENTES
ON PEDIDOS.CO_CLIENTE = CLIENTES.CO_CLIENTE
UNDAC SBD I
Ing. Williams A. Muoz Robles 18
-- La clausula WHERE se aplica antes de realizar el calculo
WHERE CLIENTES.NOMBRE != 'UN NOMBRE'
GROUP BY CLIENTES.NOMBRE,
CLIENTES.APELLIDO1,
CLIENTES.APELLIDO2
La clusula HAVING
Es posible que necesitemos calcular un agregado, pero que no necesitemos obtener
todos los datos, solo los que cumplan una condicin del agregado. Por ejemplo,
podemos calcular el valor de las ventas por producto, pero que solo queramos ver los
datos de los productos que hayan vendido ms o menos de una determinada cantidad.
En estos casos debemos utilizar la clusula HAVING.
Una vez que GROUP BY ha combinado los registros, HAVING muestra cualquier
registro agrupado por la clusula GROUP BY que satisfaga las condiciones de la
clusula HAVING. Se utiliza la clusula WHERE para excluir aquellas filas que no
desea agrupar, y la clusula HAVING para filtrar los registros una vez agrupados.
HAVING es similar a WHERE, determina qu registros se seleccionan pero despus
de calcular el agregado. Una vez que los registros se han agrupado utilizando GROUP
BY, HAVING determina cuales de ellos se van a mostrar. HAVING permite el uso de
funciones agregadas.
SELECT CLIENTES.NOMBRE,
CLIENTES.APELLIDO1,
CLIENTES.APELLIDO2,
SUM(PRECIO) -- Total del pedido
FROM DETALLE_PEDIDO
INNER JOIN PEDIDOS
ON DETALLE_PEDIDO.CO_PEDIDO = PEDIDOS.CO_PEDIDO
INNER JOIN CLIENTES
ON PEDIDOS.CO_CLIENTE = CLIENTES.CO_CLIENTE
UNDAC SBD I
Ing. Williams A. Muoz Robles 19
-- La clausula WHERE se aplica antes de realizar el calculo
WHERE CLIENTES.NOMBRE != 'UN NOMBRE'
GROUP BY CLIENTES.NOMBRE,
CLIENTES.APELLIDO1,
CLIENTES.APELLIDO2
HAVING SUM(PRECIO) > 100
Funciones agregadas.
Transact SQL pone a nuestra disposicin multiples funciones agregadas, las ms
comunes son:
MAX
MIN
COUNT
SUM
AVG
AVG
Calcula la media aritmtica de un conjunto de valores contenidos en un campo
especificado de una consulta. Su sintaxis es la siguiente
AVG(<expr>)
En donde expr representa el campo que contiene los datos numricos para los que se
desea calcular la media o una expresin que realiza un clculo utilizando los datos de
dicho campo. La media calculada por Avg es la media aritmtica (la suma de los
valores dividido por el nmero de valores). La funcin Avg no incluye ningn campo
Null en el clculo.
UNDAC SBD I
Ing. Williams A. Muoz Robles 20
SELECT CLIENTES.NOMBRE,
CLIENTES.APELLIDO1,
CLIENTES.APELLIDO2,
AVG(PRECIO) -- Promedio del pedido
FROM DETALLE_PEDIDO
INNER JOIN PEDIDOS
ON DETALLE_PEDIDO.CO_PEDIDO = PEDIDOS.CO_PEDIDO
INNER JOIN CLIENTES
ON PEDIDOS.CO_CLIENTE = CLIENTES.CO_CLIENTE
GROUP BY CLIENTES.NOMBRE,
CLIENTES.APELLIDO1,
CLIENTES.APELLIDO2
Count
Calcula el nmero de registros devueltos por una consulta. Su sintaxis es la siguiente:
COUNT(<expr>)
En donde expr contiene el nombre del campo que desea contar. Los operandos de
expr pueden incluir el nombre de un campo de una tabla, una constante o una funcin
(la cual puede ser intrnseca o definida por el usuario pero no otras de las funciones
agregadas de SQL). Puede contar cualquier tipo de datos incluso texto.
Aunque expr puede realizar un clculo sobre un campo, Count simplemente cuenta el
nmero de registros sin tener en cuenta qu valores se almacenan en los registros. La
funcin Count no cuenta los registros que tienen campos null a menos que expr sea el
carcter comodn asterisco (*). Si utiliza un asterisco, Count calcula el nmero total de
registros, incluyendo aquellos que contienen campos null. Count(*) es
considerablemente ms rpida que Count(Campo).
UNDAC SBD I
Ing. Williams A. Muoz Robles 21
SELECT COUNT(*)
FROM PEDIDOS
SELECT CLIENTES.NOMBRE, COUNT(*)
FROM PEDIDOS
INNER JOIN CLIENTES
ON PEDIDOS.CO_CLIENTE = CLIENTES.CO_CLIENTE
GROUP BY CLIENTES.NOMBRE
Max, Min
Devuelven el mnimo o el mximo de un conjunto de valores contenidos en un campo
especifico de una consulta. Su sintaxis es:
MIN(<expr>)
MAX(<expr>)
En donde expr es el campo sobre el que se desea realizar el clculo. Expr pueden
incluir el nombre de un campo de una tabla, una constante o una funcin (la cual
puede ser intrnseca o definida por el usuario pero no otras de las funciones agregadas
de SQL).
SELECT CLIENTES.NOMBRE,
MIN(PEDIDOS.FX_ALTA),
MAX(PEDIDOS.FX_ALTA)
FROM PEDIDOS
INNER JOIN CLIENTES
ON PEDIDOS.CO_CLIENTE = CLIENTES.CO_CLIENTE
GROUP BY CLIENTES.NOMBRE
UNDAC SBD I
Ing. Williams A. Muoz Robles 22
Sum
Devuelve la suma del conjunto de valores contenido en un campo especifico de una
consulta. Su sintaxis es:
SUM(<expr>)
En donde expr respresenta el nombre del campo que contiene los datos que desean
sumarse o una expresin que realiza un clculo utilizando los datos de dichos campos.
Los operandos de expr pueden incluir el nombre de un campo de una tabla, una
constante o una funcin (la cual puede ser intrnseca o definida por el usuario pero no
otras de las funciones agregadas de SQL).
SELECT CLIENTES.NOMBRE,
SUM(PEDIDOS.TOTAL_PEDIDO)
FROM PEDIDOS
INNER JOIN CLIENTES
ON PEDIDOS.CO_CLIENTE = CLIENTES.CO_CLIENTE
GROUP BY CLIENTES.NOMBRE
Uso de Select TOP con consultas agregadas.
Podemos utilizar SELECT TOP con consultas agregadas como con cualquier otra
instruccin Transact SQL.
En estos casos, la clusula TOP se aplica despus de calcular el agregado, devolviendo
las N filas indicadas.
En este escenario es posible que queramos obtener los N valores que satisfagan una
condicin. Por ejemplo, queremos si queremos obtener los tres primeros clientes con
mayores pedidos, usaremos una consulta parecida a esta:
UNDAC SBD I
Ing. Williams A. Muoz Robles 23
SELECT TOP 3
CLIENTES.NOMBRE,
SUM(DETALLE_PEDIDO.PRECIO)
FROM DETALLE_PEDIDO
INNER JOIN PEDIDOS
ON DETALLE_PEDIDO.CO_PEDIDO = PEDIDOS.CO_PEDIDO
INNER JOIN CLIENTES
ON PEDIDOS.CO_CLIENTE = CLIENTES.CO_CLIENTE
GROUP BY CLIENTES.NOMBRE
ORDER BY 2 -- SUM(DETALLE_PEDIDO.PRECIO_UNIDAD)
Sin embargo, puede darse el caso, de que el cuarto cliente devuelto por la consulta
tenga un valor agregado idntico al tercero, (es decir, estn empatados). El uso de
TOP 3 discriminara el cuarto registro. Para evitar este comportamiento, y que la
consulta devuelva tambin al cuarto cliente utilizamos la clusula WITH TIES.
SELECT TOP 3 WITH TIES
CLIENTES.NOMBRE,
SUM(DETALLE_PEDIDO.PRECIO)
FROM DETALLE_PEDIDO
INNER JOIN PEDIDOS
ON DETALLE_PEDIDO.CO_PEDIDO = PEDIDOS.CO_PEDIDO
INNER JOIN CLIENTES
ON PEDIDOS.CO_CLIENTE = CLIENTES.CO_CLIENTE
GROUP BY CLIENTES.NOMBRE
ORDER BY 2 -- SUM(DETALLE_PEDIDO.PRECIO_UNIDAD)
UNDAC SBD I
Ing. Williams A. Muoz Robles 24
Subconsultas
Definicin de subconsultas.
Una subconsulta es una sentencia SELECT que aparece dentro de otra sentencia
SELECT. Normalmente se utilizan para filtrar una clausula WHERE o HAVING con el
conjunto de resultados de la subconsulta, aunque tambin pueden utilizarse en la lista
de seleccin.
Por ejemplo podriamos consultar el alquirer ltimo de un cliente.
SELECT CO_CLIENTE, NOMBRE, MARCA, MODDELO
FROM ALQUILERES
WHERE CO_CLIENTE = 1
AND FECHA_ALQUILER = (SELECT MAX(FECHA_ALQUILER)
FROM ALQUILERES
WHERE CO_CLIENTE = 1)
En este caso, la subconsulta se ejecuta en primer lugar, obteniendo el valor de la
mxima fecha de alquier, y posteriormente se obtienen los datos de la consulta
principal.
Una subconsulta tiene la misma sintaxis que una sentencia SELECT normal
exceptuando que aparece encerrada entre parntesis.
La subconsulta se puede encontrar en la lista de seleccin, en la clusula WHERE o en
la clusula HAVING de la consulta principal.
Tiene las siguientes reestricciones:
No puede contener la clusula ORDER BY
No puede ser la UNION de varias sentencias SELECT
Si la subconsulta aparece en la lista de seleccin,o esta asociada a un operador igual "="
solo puede devolver un nico registro.
UNDAC SBD I
Ing. Williams A. Muoz Robles 25
Referencias externas
A menudo, es necesario, dentro del cuerpo de una subconsulta, hacer referencia al
valor de una columna de la fila actual en la consulta principal, ese nombre de columna
se denomina referencia externa.
Una referencia externa es un campo que aparece en la subconsulta pero se refiere a la
una de las tablas designadas en la consulta principal.
Cuando se ejecuta una consulta que contiene una subconsulta con referencias
externas, la subconsulta se ejecuta por cada fila de la consulta principal.
En este ejemplo la subconsulta aparece en la lista de seleccin, ejecutandose una vez
por cada fila que devuelve la consulta principal.
SELECT CO_EMPLEADO,
NOMBRE,
(SELECT MI N(FECHA_NOMINA)
FROM NOMINAS
WHERE CO_EMPLEADO = EMPLEADOS.CO_EMPLEADO) PRIMERA_NOMINA
FROM EMPLEADOS;
Anidar subconsultas
Las subconsultas pueden anidarse de forma que una subconsulta
aparezca en la clusula WHERE (por ejemplo) de otra subconsulta que a
su vez forma parte de otra consulta principal.
SELECT CO_EMPLEADO,
EMPLEADOS
FROM EMPLEADOS
WHERE CO_EMPLEADO IN (SELECT CO_EMPLEADO
FROM NOMINAS
WHERE ESTADO I N ( SELECT ESTADO
UNDAC SBD I
Ing. Williams A. Muoz Robles 26
FROM ESTADOS_NOMINAS
WHERE EMITIDO = 'S'
AND PAGADO = ' N' )
)
Los resultados que se obtienen con subconsultas normalmente pueden conseguirse a
travs de consultas combinadas ( J OIN ).
SELECT CO_EMPLEADO,
NOMBRE
FROM EMPLEADOS
WHERE ESTADO IN (SELECT ESTADO
FROM ESTADOS
WHERE ACTIVO = 'S')
Podr escribirse como :
SELECT CO_EMPLEADO,
NOMBRE
FROM EMPLEADOS, ESTADOS
WHERE EMPLEADOS.ESTADO = ESTADOS.ESTADO
AND ESTADOS.ACTIVO = 'S'
Normalmente es ms rpido utilizar un J OIN en lugar de una subconsulta, aunque
esto depende sobre todo del diseo de la base de datos y del volumen de datos que
tenga.
La funcin EXISTS
EXISTS es una funcin SQL que devuelve veradero cuando una subconsulta retorna al
menos una fila.
UNDAC SBD I
Ing. Williams A. Muoz Robles 27
SELECT CO_CLIENTE,
NOMBRE
FROM CLIENTES
WHERE EXISTS ( SELECT *
FROM MOROSOS
WHERE CO_CLIENTE = CLIENTES.CO_CLIENTE
AND PAGADO = 'N')
La funcin EXISTS puede ser utilizada en cualquier sentencia SQL vida, SELECT,
UPDATE, INSERT o DELETE.
UNDAC SBD I
Ing. Williams A. Muoz Robles 28
Select FOR XML
Clausula FOR XML.
A partir de la version 2000 SQL Server incluye la clausula FOR XML para la consultas.
Sin embargo, es a partir de la versin 2005 cuando se integra XML como tipo de dato
nativo.
Cuando especificamos la clausula FOR XML el resultado de la consulta es devuelto en
formato XML.
La clausula FOR XML admite los siguientes modos que representan el formato en el que el XML
es devuelto:
XML AUTO, el modo AUTO emplea los campos en la declaracin SELECT para formar
una jerarqua simple XML.
XML RAW, el modo RAW genera elementos nicos, los cuales se denominan row, por
cada fila retornada.
EXPLICIT, el modo EXPLICIT requiere un formato especfico que puede ser mapeado en
casi cualquier forma XML, y al mismo tiempo ser formulado por una sola consulta SQL.
Adicionalmente, disponemos de dos opciones ms TYPE y ELEMENTS que determinan el
formato del XML resultante. Los vemos con ejemplos.
Un ejemplo de XML AUTO.
SELECT CO_FAMILIA, FAMILIA
FROM FAMILIAS
ORDER BY FAMILIA
FOR XML AUTO, TYPE
Obtendremos el siguiente resultado:
UNDAC SBD I
Ing. Williams A. Muoz Robles 29
<FAMILIAS CO_FAMILIA="1" FAMILIA="FAMILIA 1" />
<FAMILIAS CO_FAMILIA="2" FAMILIA="FAMILIA 2" />
<FAMILIAS CO_FAMILIA="3" FAMILIA="FAMILIA 3" />
<FAMILIAS CO_FAMILIA="4" FAMILIA="FAMILIA 4" />
Podemos obtener el resultado como elementos de la siguiente forma:
SELECT CO_FAMILIA, FAMILIA
FROM FAMILIAS
FOR XML AUTO, ELEMENTS
Obtendremos el siguiente resultado:
<FAMILIAS>
<CO_FAMILIA>1</CO_FAMILIA>
<FAMILIA>FAMILIA 1</FAMILIA>
</FAMILIAS>
<FAMILIAS>
<CO_FAMILIA>2</CO_FAMILIA>
<FAMILIA>FAMILIA 2</FAMILIA>
</FAMILIAS>
<FAMILIAS>
<CO_FAMILIA>3</CO_FAMILIA>
<FAMILIA>FAMILIA 3</FAMILIA>
</FAMILIAS>
<FAMILIAS>
<CO_FAMILIA>4</CO_FAMILIA>
<FAMILIA>FAMILIA 4</FAMILIA>
</FAMILIAS>
Ahora un ejemplo de XML RAW:
UNDAC SBD I
Ing. Williams A. Muoz Robles 30
SELECT CO_FAMILIA, FAMILIA
FROM FAMILIAS
ORDER BY FAMILIA
FOR XML RAW , TYPE
Obtenemos el siguiente resultado:
<row CO_FAMILIA="1" FAMILIA="FAMILIA 1" />
<row CO_FAMILIA="2" FAMILIA="FAMILIA 2" />
<row CO_FAMILIA="3" FAMILIA="FAMILIA 3" />
<row CO_FAMILIA="4" FAMILIA="FAMILIA 4" />
Podemos obtener el resultado como elementos de la siguiente forma:
<row>
<CO_FAMILIA>1</CO_FAMILIA>
<FAMILIA>FAMILIA 1</FAMILIA>
</row>
<row>
<CO_FAMILIA>2</CO_FAMILIA>
<FAMILIA>FAMILIA 2</FAMILIA>
</row>
<row>
<CO_FAMILIA>3</CO_FAMILIA>
<FAMILIA>FAMILIA 3</FAMILIA>
</row>
<row>
<CO_FAMILIA>4</CO_FAMILIA>
<FAMILIA>FAMILIA 4</FAMILIA>
</row>
Tambin es posible especificar el nodo que queremos que muestre:
UNDAC SBD I
Ing. Williams A. Muoz Robles 31
SELECT CO_FAMILIA, FAMILIA
FROM FAMILIAS
ORDER BY FAMILIA
FOR XML RAW ('FamiliasDeProductos') , TYPE
Devuelve el siguiente resultado:
<FamiliasDeProductos CO_FAMILIA="1" FAMILIA="FAMILIA 1" />
<FamiliasDeProductos CO_FAMILIA="2" FAMILIA="FAMILIA 2" />
<FamiliasDeProductos CO_FAMILIA="3" FAMILIA="FAMILIA 3" />
<FamiliasDeProductos CO_FAMILIA="4" FAMILIA="FAMILIA 4" />
Del mismo modo con la opcin ELEMENTS:
SELECT CO_FAMILIA, FAMILIA
FROM FAMILIAS
ORDER BY FAMILIA
FOR XML RAW ('FamiliasDeProductos') , ELEMENTS
Obtendremos el siguiente resultado:
<FamiliasDeProductos>
<CO_FAMILIA>1</CO_FAMILIA>
<FAMILIA>FAMILIA 1</FAMILIA>
</FamiliasDeProductos>
<FamiliasDeProductos>
<CO_FAMILIA>2</CO_FAMILIA>
<FAMILIA>FAMILIA 2</FAMILIA>
</FamiliasDeProductos>
<FamiliasDeProductos>
<CO_FAMILIA>3</CO_FAMILIA>
<FAMILIA>FAMILIA 3</FAMILIA>
UNDAC SBD I
Ing. Williams A. Muoz Robles 32
</FamiliasDeProductos>
<FamiliasDeProductos>
<CO_FAMILIA>4</CO_FAMILIA>
<FAMILIA>FAMILIA 4</FAMILIA>
</FamiliasDeProductos>
Ahora un ejemplo con el formato XML EXPLICIT.
SELECT
1 AS TAG, -- La primera columna debe tener el alias TAG
NULL AS PARENT, -- La segunda columna debe tener el alias PARENT
-- El resto de columnas deben tener el alias en el formato:
-- <NombreNodo>!<nodo>!<atributo>
CO_FAMILIA as "FamiliaDeProductos!1!CODIGO_FAMILIA",
FAMILIA as "FamiliaDeProductos!1!DESCRIPCION"
FROM FAMILIAS
ORDER BY FAMILIA
FOR XML EXPLICIT
Obtenemos el siguiente resultado:
<FamiliaDeProductos CODIGO_FAMILIA="1" DESCRIPCION="FAMILIA 1" />
<FamiliaDeProductos CODIGO_FAMILIA="2" DESCRIPCION="FAMILIA 2" />
<FamiliaDeProductos CODIGO_FAMILIA="3" DESCRIPCION="FAMILIA 3" />
<FamiliaDeProductos CODIGO_FAMILIA="4" DESCRIPCION="FAMILIA 4" />
Campos y variables XML.
Dado que XML es un tipo nativo de XML podemos definir tablas con campos de tipo
XML, variables ...
El siguiente ejemplo muestra como trabajar con campos y variables XML.
UNDAC SBD I
Ing. Williams A. Muoz Robles 33
-- Primero creamos una tabla con un campo XML
CREATE TABLE tablaXML
(
ID int not null identity,
DOC xml null,
constraint PK_tablaXML PRIMARY KEY (ID)
)
GO
DECLARE @xml xml -- Variable de tipo XML
-- Leemos los datos de la tabla FAMILIAS
SET @xml = (SELECT CO_FAMILIA, FAMILIA
FROM FAMILIAS FOR XML AUTO)
-- y los guardamos en nuestra tabla
INSERT INTO tablaXML
(DOC) VALUES (@xml)
-- Hacemos lo mismo con los productos
SET @xml = (SELECT *
FROM PRODUCTOS FOR XML AUTO)
INSERT INTO tablaXML
(DOC) VALUES (@xml)
-- Consultamos la tabla y vemos el resultado
SELECT * FROM tablaXML
Cuando consultemos la tabla tendremos la siguiente informacin (en mi caso claro!):
UNDAC SBD I
Ing. Williams A. Muoz Robles 34
<!--Registro de la tabla familias-->
<FAMILIAS CO_FAMILIA="1" FAMILIA="FAMILIA 1" />
<FAMILIAS CO_FAMILIA="2" FAMILIA="FAMILIA 2" />
<FAMILIAS CO_FAMILIA="3" FAMILIA="FAMILIA 3" />
<FAMILIAS CO_FAMILIA="4" FAMILIA="FAMILIA 4" />
<!--Registro de la tabla Productos-->
<PRODUCTOS CO_PRODUCTO="1" CO_CATEGORIA="1" PRODUCTO="PRODUCTO 1"
/>
<PRODUCTOS CO_PRODUCTO="2" CO_CATEGORIA="1" PRODUCTO="PRODUCTO 2"
/>
<PRODUCTOS CO_PRODUCTO="3" CO_CATEGORIA="2" PRODUCTO="PRODUCTO 3"
/>

Potrebbero piacerti anche