Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

Siempre que tengamos consultas complejas, donde intervienen varias tablas y además hay varios filtros, se nos puede hacer un lío. Ya hay muy buenos artículos sobre el uso subconsultas con SQL en la web: The Power of Subqueries, Using a Subquery in a T-SQL Statement.

Sólo voy a dar un ejemplo sencillo de como usar estas. Tenemos el siguiente modelo, por cierto es un modelo básico, a noticia verdadera le faltan muchos más campos:

Y se me presenta la necesidad de traer todas las noticias con el tag 'Microsoft'. La consulta sería asi:

   SELECT * FROM Noticias.Noticia noti
        WHERE noti.NOTCod in (
                   SELECT notTag.NOTCod 
                   FROM Noticias.Tag tag
                        INNER JOIN Noticias.NoticiaTag notTag 
                        ON tag.TAGCod = notTag.TAGCod
                   WHERE tag.TAGNombre = 'Microsoft' )

Como pueden apreciar, en este caso la subconsulta devuelve todos los código de las noticias con el tag enviado, y sólo recuperaré las noticias cuyo código esté dentro de ese rango. Podrían decir que con sólo usar JOINs se puede también hacer, pero normalmente nuestras tablas no tendrán esta estructura, la cantidad de tablas que participan en la consulta también será mayor, y habrá muchos más filtros, por ejemplo filtro por el área, filtro por las noticias publicadas, entre otros. En el caso de que quisiéramos filtrar las noticias publicadas, sólo habría que agregar un AND y la condición al WHERE de la consulta de arriba.

Las subconsultas se pueden usar en:

  • En el listado de las columnas de una consulta SELECT.
  • En una clausula WHERE, el ejemplo de arriba.
  • En una clausula FROM.
  • En una clausula FROM de una consulta UPDATE.
  • En una clausula HAVING.

Para revisar ejemplos de uso de subconsultas, visitar:

Por cierto, revisaba un post de Percy Reyes, donde hablaba de SubQueries vs INNER JOINs, y en uno de los comentarios, PabloNetrix, comentaba que tenía consultas que toman 45 minutos. Y es que si queremos optimizar queries, no sólo debemos valernos de subconsultas, ya Rodrigo, hablo del uso de índices, también se debe hacer uso del plan de ejecución de SQL, para observar, interpretar, y tunear nuestros queries. Además, para saber si lo que estamos haciendo va bien, o que más podemos hacer. Por cierto encontré estos links: Cómo solucionar problema de consultas de ejecución lenta en SQL Server 7.0 o versiones posteriores, y Mostrar planes de ejecución gráficos (SQL Server Management Studio).

Saludos,


Post cruzado 3Dev Blogs
Published 16/2/2007 17:43 por Sergio Tarrillo
Archivado en:
Comparte este post:
http://geeks.ms/blogs/sergiotarrillo/archive/2007/02/16/10582.aspx

Comentarios

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

Creo que "exists" para estos casos es mas eficiente que la "in":

SELECT * FROM Noticias.Noticia noti

WHERE exists  (SELECT 1

              FROM Noticias.Tag tag INNER JOIN Noticias.NoticiaTag notTag

                       ON tag.TAGCod = notTag.TAGCod

              WHERE tag.TAGNombre = 'Microsoft' and notTag.NotCod = noti.NOTCod)

Saturday, February 17, 2007 9:08 AM por Pirri

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

Hola Pirri!

Muchas gracias por el aporte, no sabía que se podía hacer de esa forma, aún estoy masticando la consulta :p.

Lo estuve probando en diversas tablas con más cantidad de datos, el plan de ejecución siempre es el mismo para los dos. Habría que probarlo con "más" datos, con consultas que tomen más de medio minuto para ver si hay diferencias en el tiempo que tarda cada consulta.

Pregunta: para los tigres en optimización de queries, si dos consultas tienen el mismo plan de ejecución, tienen el mismo grado de eficiencia?, o no necesariamente?

Saludos,

Saturday, February 17, 2007 10:08 AM por Sergio Tarrillo

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

Ups, creo que no he conseguido publicar lo que queria. Segundo intento:

En http://www.sql-server-performance.com/transact_sql.asp puedes ver algunos consejos acerca del EXISTS. Como verás, en resumen, suele ser mas eficiente que In porque mientras que este necesita que se obtengan todos los registros de la subquery, con el exists la subquery finaliza en cuanto encuentre el primer registro que cumpla la condicion.

Saturday, February 17, 2007 12:39 PM por Pirri

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

"...suele ser mas eficiente que In porque mientras que este necesita que se obtengan todos los registros de la subquery, con el exists la subquery finaliza en cuanto encuentre el primer registro que cumpla la condicion."

Lo cual efectivamente tiene su lógica.

Por cierto una duda: Donde has escrito

"WHERE exists (SELECT 1",

¿no habrás querido decir realmente

"WHERE exists (SELECT TOP 1" ?

Una curiosidad más acerca de las consultas (bueno en este caso, en realidad es acerca del Optimizador): ¿Sabíais que hacer

"SELECT COUNT(*) FROM..."

es lo mismo que

"SELECT COUNT(CampoID) FROM..." ?

Pues sí, comprobado con el Analizador. :-)

Saludos

Saturday, February 17, 2007 1:10 PM por PabloNetrix

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

No, donde digo select 1 quiero decir select 1. La clausula exists no necesita devolver datos, asi que en vez de poner un * o el nombre de un campo pues pongo el dato mas pequeño que se me ocurre: un 1. Con eso es bastante. Pero podia haber puesto "select noti.NOTCod" o "select 'hola'"...

Con respecto al select count, tambien funciona si pones select count(1) :P

Saludos!

Saturday, February 17, 2007 9:44 PM por Pirri

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

Que loko!. Ahora si queda claro, bueno eso creo, gracias por el dato Pirri!

Resumiendo el detalle para todos: Comparando las clauslas EXISTS e IN en los escenarios mostrarados arriba. Las dos consultas retornan los mismos datos, usando IN, por cada fila recupera el subquery (con todos los datos) y compara si esta en ese rango. En cambio con EXISTS, por cada fila veríciará si existe esa fila del subquery, el SELECT 1, en este caso trabajará como un booleano, ya que si existe el registro retornará una fila con una celda 1, y si no retorna cero filas, el exists verificará si existen filas, osea que es igual poner SELECT 1, SELECT 2, o el numero que se me ocurrá, colocar un string, o poner *, es distinto, ya el resultado será el mismo, sólo se usa como un flag.

Pirri, hay algo más que se necesite detallar?

Saludos,

Saturday, February 17, 2007 9:50 PM por Sergio Tarrillo

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

Olvidé enviar esta enlace :$: http://msdn2.microsoft.com/es-es/library/ms188336.aspx. Por cierto, el mensaje anterior se escribió sin saber que Pirri también estaba enviando un comentario :P.

Saludos,

Saturday, February 17, 2007 9:51 PM por Sergio Tarrillo

# SqlServerForum.org » Blog Archive » Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

1. Desplegar el estudiante que más asignaturas esta cursando.

Thursday, March 1, 2007 9:01 PM por resolver esta consulta

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

¿?

Wednesday, March 14, 2007 7:01 PM por Sergio Tarrillo

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

Hola me gustó mucho tu artículo. Solo tengo una pregunta. Estoy realizando subconsultas en un select, para traer una columna extra con el promedio de los salarios de los clientes. Me dicen que eso es ineficiente.  Que es mejor realizar un join con una subconsulta que traiga dicho total.  Al realizar los test de performance de ambas, es mas eficiente la primera.  Preciento que es debido a que realizar el join con una subconsulta, es crear una tabla "temporal" que no posee indices. Si esta bien mi apreciación?.  Cual sería la mejor manera de evaluarlo?.

Monday, March 26, 2007 11:39 PM por Julián Castiblanco

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

no conosco muchas herramientas para comparar performance, voy a buscar y te cuento..

Saludos,

Wednesday, April 25, 2007 5:55 AM por Sergio Tarrillo

# se puede ser un buen desarrollador sin saber el lenguaje de la base datos que estamos usando?

y yo creo que depende, por lo menos uno dentro de un equipo de desarrollo debe saberlo. Pero en general...

Sunday, June 17, 2007 1:31 AM por Sergio Tarrillo's Blog -> enhancements

# se puede ser un buen desarrollador sin saber el lenguaje de la base datos que estamos usando?

y yo creo que depende, por lo menos uno dentro de un equipo de desarrollo debe saberlo. Pero en general

Sunday, June 17, 2007 1:31 AM por SergioTarrillo's RichWeblog

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

Tengo dos Tablas A y B relacionadas de 1 a N , A es la Entidad Fuerte y B la debil.

Entonces tenemos que cada Registro en la Tabla A tiene N Registros en la Tabla B.

Bien lo que necesto es sacar Los Ultimos registros de la Tabla B , para cada registro en A .  

La verdad lo he pensado de muchas formas y no he podido , desde ya les agradezco.

Thursday, August 23, 2007 10:08 PM por Alvaro

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

a que exactamente te refieres con sacar los últimos registros?, puedes usar la clausula WHERE (filtros) y TOP (para sacar los primeros n registros). Si quisieras los ultimos registros de la consulta, puedes hacer un ORDER BY inverso, y usar un TOP.

Saludos,

Monday, August 27, 2007 2:29 AM por sergiotarrilllo

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

Bueno... un consulta si quieres asignarle un nombre a la subconsulta como arias y en que parte va la asignación del nombre? a si tienes mas ejemplos me lo podrias enviar con la base de datos northwin, gracias!

responde a ste correo yor_air77@hotmail.com

Tuesday, September 25, 2007 3:06 PM por Roy

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

Como puedo generar una subconsulta en SQL navigator?????

Tuesday, September 25, 2007 6:15 PM por FRANCO

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

que mierda de nombres le habeis puesto a las tablas del ejemplo

Sunday, November 2, 2008 3:05 AM por hola

# re: Usando subconsultas en SQL, para reducir la complejidad de nuestros queries

que mierda de nombres le  habeis puesto a las tablas del ejemplo

Sunday, November 2, 2008 3:06 AM por hola

# consutal SQL

Treaer los ultimos  25 registro de cada producto vendido en unas fechas

Wednesday, January 21, 2009 6:21 PM por martin

# se requiere consultas con subconsultas y con subtotales y totales

por favor mandenme un consulta compleja

Thursday, May 20, 2010 8:48 PM por efrain