You are on page 1of 11

Administrando los subquerys (subconsultas SQL)

Un subquery es una instruccin SELECT que est anidado dentro de otro T-SQL. Una instruccin
SELECT subquery se ejecuta de forma independiente de la T-SQL, en el que est anidado y
devolver un conjunto de resultados. Una instruccin SELECT subquery puede ser nica y no
depende de la declaracin en la que est anidado; adems puede devolver cualquier nmero de
valores, y se puede encontrar en la lista de columnas de una instruccin SELECT, el FROM, GROUP
BY, HAVING, y / o clusulas ORDER BY de una instruccin T-SQL. Un subquery puede ser utilizado
como un parmetro a una llamada de funcin. Bsicamente, una subquery puede ser utilizado en
cualquier expresin.

En los siguientes ejemplos se muestran los casos ms importantes del gran poder de los subquerys
son:

El uso de una subconsulta en la lista de columnas de una instruccin SELECT:

Supongamos que usted desea ver el pasado y el IdPedido OrderDate de la ltima orden que fue
enviada a Pars. Junto con esa informacin, dice que tambin le gustara ver el OrderDate de la
ltima orden de envo, independientemente de la CiudadDestinatario. Adems de esto, tambin
quisiera para calcular la diferencia de das entre las dos OrderDates diferentes. Aqu est mi T-SQL
SELECT para lograr esto:


SELECT TOP 1 OrderId,
CONVERT(CHAR(10), OrderDate,121) Last_Paris_Order,
(SELECT CONVERT(CHAR(10),MAX(OrderDate),121)
FROM Northwind.dbo.Orders) Last_OrderDate,
DATEDIFF(dd,OrderDate,(SELECT MAX(OrderDate)
FROM Northwind.dbo.Orders)) Day_Diff
FROM Northwind.dbo.Orders
WHERE ShipCity = 'Paris'
ORDER BY OrderDate DESC

El uso de una subconsulta en la clusula WHERE:

Supongamos que una empresa le gustara hacer algo de marketing especficas. Este marketing
dirigido pondra en contacto con los clientes en el pas con el menor nmero de pedidos. Se espera
que este marketing dirigidas a aumentar las ventas totales en el pas en cuestin. Aqu hay un
ejemplo que utiliza una subconsulta para devolver la informacin de contacto del cliente para el
pas con el menor nmero de pedidos:

SELECT Country,
CompanyName,
ContactName,
ContactTitle,
Phone
FROM Northwind.dbo.Customers
WHERE country = (SELECT TOP 1 country
FROM Northwind.dbo.Customers C
JOIN Northwind.dbo.Orders O
ON C.CustomerId = O.CustomerID
GROUP BY country
ORDER BY count(*))

Aqu hemos escrito una subconsulta que se une a la de clientes y las tablas para determinar el
nmero total de pedidos de cada pas.

El uso de una subconsulta en la clusula FROM:

La clusula FROM identifica normalmente las tablas utilizadas en el T-SQL. Usted puede pensar de
cada uno de los cuadros sealados en la clusula FROM como un conjunto de registros. Bueno,
una subconsulta es slo un conjunto de registros, y por lo tanto puede ser utilizada en la clusula
FROM como una tabla. Aqu hay un ejemplo donde se utiliza una subconsulta en la clusula FROM
de una instruccin SELECT:

SELECT au_lname,
au_fname,
title FROM (SELECT au_lname, au_fname, au_id
FROM pubs.dbo.authors
WHERE state = 'CA') as A
JOIN pubs.dbo.titleauthor ta ON A.au_id = ta.au_id
JOIN pubs.dbo.titles t ON ta.title_id = t.title_id

Subquery en la clusula FROM de una instruccin UPDATE:
SET NOCOUNT ON
CREATE TABLE x(
i INT IDENTITY,
a CHAR(1))
INSERT INTO x VALUES ('A')
INSERT INTO x VALUES ('B')
INSERT INTO x VALUES ('C')
INSERT INTO x VALUES ('D')
SELECT * FROM x
UPDATE x
SET a = b.a
FROM (SELECT MAX(a) AS a FROM x) b
WHERE I > 2

SELECT * FROM x
DROP TABLE x

SELECT * FROM x
DROP TABLE x

Aqu hemos creado una tabla denominada "x" que tiene cuatro filas. Luego se procedi a
actualizar los registros en que "i" es mayor que 2, con el valor mximo en la columna "a". Usamos
un subquery en la clusula FROM de la instruccin UPDATE a la identidad del valor mximo de la
columna "a".

El uso de una subconsulta en la clusula HAVING:

En el siguiente ejemplo, se utiliz una subconsulta para encontrar el nmero de libros que la
editorial ha publicado en la editorial no se encuentra en el estado de California. Para lograr esto se
utiliz una subconsulta en una clusula HAVING. Aqu est el cdigo:

SELECT pub_name,
COUNT(*) bookcnt
FROM pubs.dbo.titles t
JOIN pubs.dbo.publishers p on t.pub_id = p.pub_id
GROUP BY pub_name
HAVING p.pub_name IN (SELECT pub_name
FROM pubs.dbo.publishers
WHERE state <> 'CA')

Subconsultas correlacionadas:

Una subconsulta correlacionada es una instruccin SELECT anidada dentro de otra instruccin T-
SQL, que contiene una referencia a una o ms columnas en la consulta externa. Por lo tanto, la
subconsulta correlacionada se puede decir que depender de la consulta externa. Esta es la
principal diferencia entre una subconsulta correlacionada y slo una subconsulta simple. Una
subconsulta simple no depende de la consulta externa, se puede ejecutar de forma independiente
de la consulta externa, y devolver un conjunto de resultados. Una subconsulta correlacionada, ya
que depende de la consulta externa devolver un error de sintaxis si se ejecuta por s mismo.

Una subconsulta correlacionada se ejecuta varias veces mientras se procesa el T-SQL que contiene
la subconsulta correlacionada. La subconsulta correlacionada se llevar a cabo una vez por cada
fila de candidatos seleccionados por la consulta externa. Las columnas de consulta externa, se
hace referencia en la subconsulta correlacionada, se sustituyen con los valores de la fila de los
candidatos antes de cada ejecucin. Dependiendo de los resultados de la ejecucin de la
subconsulta correlacionada, se determinar si la fila de la consulta externa se devuelve en el
resultado final.

Uso de una subconsulta correlacionada en una clusula WHERE:

Supongamos que desea un informe de todos "OrderID", donde el cliente no compra ms del 10%
de la cantidad media vendida para un producto determinado. De esta manera usted puede revisar
estas rdenes, y, posiblemente, en contacto con los clientes, para ayudar a determinar si haba
una razn para la orden de baja cantidad. Una subconsulta correlacionada en una clusula WHERE
puede ayudarle a producir este informe. Aqu est una instruccin SELECT que produce la lista
deseada de "OrderID's":

SELECT DISTINCT OrderId
FROM Northwind.dbo.[Order Details] OD
WHERE Quantity > (SELECT AVG(Quantity) * .1
FROM Northwind.dbo.[Order Details]
WHERE OD.ProductID = ProductID)

Subconsultas correlacionadas en la clusula HAVING

Diga sus organizaciones quiere ejecutar un programa de incentivos de un ao de duracin para
aumentar los ingresos. Por lo tanto, se anuncian a sus clientes que si cada orden en que lugar,
durante el ao, es ms de $ 750 que les dar un descuento al final del ao en la tasa de de $ 75
por orden en que lugar. A continuacin se muestra un ejemplo de cmo calcular el importe de la
devolucin. En este ejemplo se utiliza una subconsulta correlacionada en la clusula de tener que
identificar a los clientes que califican para recibir el reembolso.

SELECT C.CustomerID,
COUNT(*) * 75 Rebate
FROM Northwind.DBO.Customers C
JOIN Northwind.DBO.Orders O ON C.CustomerID = O.CustomerID
WHERE DATEPART(yy,OrderDate) = '1998'
GROUP BY C.CustomerId
HAVING 750 < ALL(SELECT SUM(UnitPrice * Quantity * (1 - Discount))
FROM Northwind.DBO.Orders O
JOIN Northwind.DBO.[Order Details] OD ON O.OrderID = OD.OrderID
WHERE O.CustomerID = C.CustomerId
AND DATEPART(yy,O.OrderDate) = '1998'
GROUP BY O.OrderId)

Select anidados SQL
Unin o concatenacin de select en SQL
El objetivo de este articulo es mostrar de forma clara y sencilla el uso de los select anidados.

Para ponernos en contexto el uso de select anidados es utilizado en ocaciones para
concatenar o unir tablas que han sido seleccionados en diferentes sentencias.

SELECT campo1,
campo2 FROM [Tabla] WHERE campoX in (SELECT campoY FROM [Tabla] WHERE campoZ='valor' )

Para el ejemplo he creado una tabla sencilla con la siguiente estructura e informacin.


Id Nombres Cedula IdPadre
15 Juan Guerra 80971165 NULL
20 Martha Gonzalez 52645854 15
41 Camilo Fernandez 90475685 15
53 German Vela 86545658 NULL
64 Lorena Lazo 80699887 53
71 Fernando Torres 73852963 53
112 Maria Vergara 56874594 NULL
152 David Gutierrez 79888654 112

Esta tabla contiene imformacin de personas y una dependencia entre ellas por medio de la
columna IdPadre.
Si necesitamos seleccionar el registro con numero de cedula numero 80971165
seleccionamos una sentencia parecida a esta:

SELECT * FROM Empleados WHERE Cedula='80971165'

Pero si adicionalmente queremos seleccionar sus hijos debemos cambiar la sentencia, y
podria ser algo como esto.

SELECT * FROM Empleados WHERE Cedula='80971165' AND IdPadre in (SELECT Id FROM Empleados
WHERE Cedula='80971165')

De esta forma tomariamos los siguientes datos.

Id Nombres Cedula IdPadre
15 Juan Guerra 80971165 NULL
20 Martha Gonzalez 52645854 15
41 Camilo Fernandez 90475685 15

Amigo, en todo caso la sentencia sera: SELECT * FROM Empleados WHERE
Cedula='80971165' AND IdPadre in (SELECT IdPadre FROM Empleados WHERE
IdPadre='15') Saludos.

Hola, Buenos Das
Agradecera que me puedan ayudar con la siguiente situacin:
Tengo dos select y me gustara anidarlos (o si hay un caso de procedimiento almacenado);
el select1 trae un valor osea un ID=VALOR, y este valor se lo quiero pasar a otro select2 para
que me traiga todos los valores resultantes de este criterio. Dejo los select para
mayor comprensin:
PRIMER SELECT, paso como parmetros fecha, servicio, cm
select C.Id
from Gestion.PerfilConductores as C
WHERE C.Fecha='26-04-2012' AND C.Servicio='T303c' AND C.CM='10:40:00'
obtengo ID=75873
SEGUNDO SELECT, paso como parmetro ID=75873
luego ese resultado se lo paso al otro select:
select top 144 *
from Gestion.PerfilConductores as P
where P.ID <= 75873
order by ID desc

Hola:
Existen varias soluciones, la ms 'facil' es juntar la sentencias en una:
select top 144 *
from Gestion.PerfilConductores as P
where P.ID <= (
select C.Id
from Gestion.PerfilConductores as C
WHERE C.Fecha='26-04-2012' AND C.Servicio='T303c' AND C.CM='10:40:00'
)
order by ID desc

96 - Exists y No Exists
Los operadores "exists" y "not exists" se emplean para determinar si hay o no datos en una lista de
valores.
Estos operadores pueden emplearse con subconsultas correlacionadas para restringir el resultado
de una consulta exterior a los registros que cumplen la subconsulta (consulta interior). Estos
operadores retornan "true" (si las subconsultas retornan registros) o "false" (si las subconsultas no
retornan registros).
Cuando se coloca en una subconsulta el operador "exists", SQL Server analiza si hay datos que
coinciden con la subconsulta, no se devuelve ningn registro, es como un test de existencia; SQL
Server termina la recuperacin de registros cuando por lo menos un registro cumple la condicin
"where" de la subconsulta.
La sintaxis bsica es la siguiente:
... where exists (SUBCONSULTA);
En este ejemplo se usa una subconsulta correlacionada con un operador "exists" en la clusula
"where" para devolver una lista de clientes que compraron el artculo "lapiz":
select cliente,numero
from facturas as f
where exists
(select *from Detalles as d
where f.numero=d.numerofactura
and d.articulo='lapiz');
Puede obtener el mismo resultado empleando una combinacin.
Podemos buscar los clientes que no han adquirido el artculo "lapiz" empleando "if not exists":
select cliente,numero
from facturas as f
where not exists
(select *from Detalles as d
where f.numero=d.numerofactura
and d.articulo='lapiz');

SQL > SQL Avanzado > Exists
En la seccin anterior, utilizamos IN para enlazar la consulta interna y la consulta
externa en una instruccin de subconsulta. IN no es la nica forma de hacerlo uno
puede utilizar muchos operadores tales como >, <, o =.EXISTS es un operador
especial que describiremos en esta seccin.
EXISTS simplemente verifica si la consulta interna arroja alguna fila. Si lo hace,
entonces la consulta externa procede. De no hacerlo, la consulta externa no se
ejecuta, y la totalidad de la instruccin SQL no arroja nada.
La sintaxis para EXISTS es
SELECT "nombre1_columna"
FROM "nombre1_tabla"
WHERE EXISTS
(SELECT *
FROM "nombre2_tabla"
WHERE "Condicin");
Por favor note que en vez de *, puede seleccionar una o ms columnas en la consulta
interna. El efecto ser idntico.
Utilizamos las mismas tablas de ejemplos:
Tabla Store_Information
Store_Name Sales Txn_Date
Los Angeles 1500 05-Jan-1999
San Diego 250 07-Jan-1999
Los Angeles 300 08-Jan-1999
Boston 700 08-Jan-1999
Table Geography
Region_Name Store_Name
East Boston
East New York
West Los Angeles
West San Diego
colocaramos la siguiente consulta SQL:
SELECT SUM(Sales) FROM Store_Information
WHERE EXISTS
(SELECT * FROM Geography
WHERE region_name = 'West');
Obtendremos el siguiente resultado:
SUM(Sales)
2750
Al principio, esto puede parecer confuso, debido a que la subsequencia incluye la
condicin [Region_Name = 'West'], an as la consulta sum los negocios para todas
las regiones. Si observamos de cerca, encontramos que debido a que la subconsulta
arroja ms de 0 filas, la condicin EXISTS es verdadera, y la condicin colocada
dentro de la consulta interna no influencia la forma en que se ejecuta la consulta
externa.
Tema 5. Las subconsultas (I)
Definiciones

Una subconsulta es una sentencia SELECT que aparece dentro de otra
sentencia SELECT que llamaremos consulta principal.
Se puede encontrar en la lista de seleccin, en la clusula WHERE o en la clusula
HAVING de la consulta principal.
Una subconsulta tiene la misma sintaxis que una sentencia SELECT normal exceptuando
que aparece encerrada entre parntesis, no puede contener la clusula ORDER BY, ni
puede ser la UNION de varias sentencias SELECT, adems tiene algunas restricciones en
cuanto a nmero de columnas segn el lugar donde aparece en la consulta principal. Estas
restricciones las iremos describiendo en cada caso.
Cuando se ejecuta una consulta que contiene una subconsulta, la subconsulta se ejecuta
por cada fila de la consulta principal.
Se aconseja no utilizar campos calculados en las subconsultas, ralentizan la consulta.
Las consultas que utilizan subconsultas suelen ser ms fciles de interpretar por el
usuario.
Referencias externas
A menudo, es necesario, dentro del cuerpo de una subconsulta, hacer referencia al valor de
una columna en la fila actual de la consulta principal, ese nombre de columna se denomina
referencia externa.
Una referencia externa es un nombre de columna que estando en la subconsulta, no se
refiere a ninguna columna de las tablas designadas en la FROM de la subconsulta sino a
unacolumna de las tablas designadas en la FROM de la consulta principal. Como la
subconsulta se ejecuta por cada fila de la consulta principal, el valor de la referencia externa ir
cambiando.

Ejemplo:

SELECT numemp, nombre, (SELECT MIN(fechapedido) FROM pedidos WHERE rep =
numemp)
FROM empleados;
En este ejemplo la consulta principal es SELECT... FROM empleados.
La subconsulta es ( SELECT MIN(fechapedido) FROM pedidos WHERE rep = numemp ).
En esta subconsulta tenemos una referencia externa ( numemp ) es un campo de la tabla
empleados (origen de la consulta principal).
Qu pasa cuando se ejecuta la consulta principal?

- se coge el primer empleado y se calcula la subconsulta sustituyendo numemp por el valor
que tiene en el primer empleado. La subconsulta obtiene la fecha ms antigua en los pedidos
del rep = 101,
- se coge el segundo empleado y se calcula la subconsulta con numemp = 102 (numemp del
segundo empleado)... y as sucesivamente hasta llegar al ltimo empleado.
Al final obtenemos una lista con el nmero, nombre y fecha del primer pedido de cada
empleado.
Si quitamos la clusula WHERE de la subconsulta obtenemos la fecha del primer pedido de
todos los pedidos no del empleado correspondiente.
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. En la prctica, una consulta consume mucho ms tiempo y memoria cuando
se incrementa el nmero de niveles de anidamiento. La consulta resulta tambin ms difcil de
leer , comprender y mantener cuando contiene ms de uno o dos niveles de subconsultas.

Ejemplo:
SELECT numemp, nombre
FROM empleados
WHERE numemp = (SELECT rep FROM pedidos WHERE clie = (SELECT numclie FROM
clientes WHERE nombre = 'Julia Antequera'))
En este ejemplo, por cada linea de pedido se calcula la subconsulta de clientes, y esto se
repite por cada empleado, en el caso de tener 10 filas de empleados y 200 filas de pedidos
(tablas realmente pequeas), la subconsulta ms interna se ejecutara 2000 veces (10 x 200).
Subconsulta en la lista de seleccin
Cuando la subconsulta aparece en la lista de seleccin de la consulta principal, en este
caso la subconsulta, no puede devolver varias filas ni varias columnas, de lo contrario se
da un mensaje de error.
Muchos SQLs no permiten que una subconsulta aparezca en la lista de seleccin de la
consulta principal pero eso no es ningn problema ya que normalmente se puede obtener lo
mismo utilizando como origen de datos las dos tablas. El ejemplo anterior se puede obtener de
la siguiente forma:
SELECT numemp, nombre, MIN(fechapedido)
FROM empleados LEFT JOIN pedidos ON empleados.numemp = pedidos.rep
GROUP BY numemp, nombre
En la clusula FROM
En la clusula FROM se puede encontrar una sentencia SELECT encerrada entre
parntesis pero ms que subconsulta sera una consulta ya que no se ejecuta para cada fila
de la tabla origen sino que se ejecuta una sola vez al principio, su resultado se combina con
las filas de la otra tabla para formar las filas origen de la SELECT primera y no admite
referencias externas.
En la clusula FROM vimos que se poda poner un nombre de tabla o un nombre de
consulta, pues en vez de poner un nombre de consulta se puede poner directamente la
sentencia SELECT correspondiente a esa consulta encerrada entre parntesis.

Subconsulta en las clusulas WHERE y
HAVING
Se suele utilizar subconsultas en las clusulas WHERE o HAVING cuando los datos que
queremos visualizar estn en una tabla pero para seleccionar las filas de esa tabla
necesitamos un dato que est en otra tabla.
Ejemplo:

SELECT numemp, nombre
FROM empleados
WHERE contrato = (SELECT MIN(fechapedido) FROM pedidos)
En este ejemplo listamos el nmero y nombre de los empleados cuya fecha de contrato sea
igual a la primera fecha de todos los pedidos de la empresa.
En una clusula WHERE / HAVING tenemos siempre una condicin y la subconsulta acta
de operando dentro de esa condicin.
En el ejemplo anterior se compara contrato con el resultado de la subconsulta. Hasta ahora las
condiciones estudiadas tenan como operandos valores simples (el valor contenido en una
columna de una fila de la tabla, el resultado de una operacin aritmtica...) ahora la
subconsulta puede devolver una columna entera por lo que es necesario definir otro tipo
de condiciones especiales para cuando se utilizan con subconsultas.

You might also like