SELECT * FROM TablaTempo WHERE id NOT IN (SELECT Folio FROM Tabla

3,630 views
Skip to first unread message

BD Learner

unread,
May 3, 2013, 3:06:16 PM5/3/13
to sistemas-gestores...@googlegroups.com
En una consulta sobre cómo saber los consecutivos faltantes:

11
12
13
15
16
17
18
19
20

El resultado de los consecutivos faltantes arrojaría que el numero 14 hace falta.

Una solución que daba LMG con VFP es esta:

CREATE CURSOR Tempo (Id I)
FOR ln=1 to 10
  INSERT INTO Tempo (Id) VALUES (ln)
ENDFOR

SELECT * FROM Tempo WHERE Id NOT IN (SELECT Folio FROM MiTabla)



La duda es para qué sirven las consultas con IN y luego un (Select etc.) dentro del paréntesis ? ..




BD Learner

unread,
May 3, 2013, 3:40:22 PM5/3/13
to sistemas-gestores...@googlegroups.com
La sintaxis dice:

SELECT column_name(s) FROM table_name WHERE column_name IN (value1,value2,..)


Pero ahi no viene otro select dentro del paréntesis..


Otra: ese IN es algo estándar en los SGBD más populares?..

Saludos!

Hernan Cano

unread,
May 3, 2013, 3:43:41 PM5/3/13
to sistemas-gestores...@googlegroups.com
Una consulta del tipo "... NOT IN (..." es para conocer los datos faltantes....y como soy programador entonces sé que son consecutivos faltantes pues lo que estoy comparando son consecutivos...
 
[me siento tonto, pues he dicho algo evidente...]
 

Walter R. Ojeda Valiente

unread,
May 3, 2013, 3:45:01 PM5/3/13
to sistemas-gestores...@googlegroups.com
Usar un SELECT dentro de otro SELECT es perfectamente admisible en SQL. La única precaución a tomar es que en muchos casos el SELECT interno debe devolver un solo valor (en terminología SQL se le llama "singleton SELECT").

Y el operador IN es estándar.

Saludos.

Walter.




2013/5/3 BD Learner <thenewin...@gmail.com>




--
Has recibido este mensaje porque estás suscrito al grupo "Sistemas Gestores de Bases de Datos" de Grupos de Google.
Visita este grupo en http://groups.google.com/group/sistemas-gestores-de-bases-de-datos?hl=es-419.
 
 



--
Hay 10 clases de personas. Las que conocen aritmética binaria y las que no.

BD Learner

unread,
May 3, 2013, 3:55:51 PM5/3/13
to sistemas-gestores...@googlegroups.com
Hola Walter,

Gracias por responder!

Entonces hasta ahora entiendo que el IN (value1,value2,..) me permite buscar más de un valor, a diferencia de usar solo el where = ?..

Es esa su ventaja?..


En este caso específico, habría un inconveniente o funcionaría si cada select interno devuelve un solo valor?..

Este ejemplo es una exageracion, pero sirve para hacer notar la pregunta:

SELECT * FROM Tempo WHERE Id IN (SELECT Folio FROM MiTabla, SELECT FolioAux FROM MiTabla )



Saludos!

Walter R. Ojeda Valiente

unread,
May 3, 2013, 5:27:50 PM5/3/13
to sistemas-gestores...@googlegroups.com
Un IN es equivalente a tener varios OR, pero se escribe menos y en general se ejecuta más rápido.

Cada uno de los SELECT internos debe devolver un solo valor.

Debes separarlos con paréntesis:

SELECT * FROM Tempo WHERE Id IN ((SELECT Folio FROM MiTabla), (SELECT FolioAux FROM MiTabla ))

Saludos.

Walter.


BD Learner

unread,
May 3, 2013, 10:21:39 PM5/3/13
to sistemas-gestores...@googlegroups.com
Magistral la explicación Walter!

Aprendo mucho cada vez que comentas..

Muy agradecido !!

Hernan Cano

unread,
May 6, 2013, 5:12:39 PM5/6/13
to sistemas-gestores...@googlegroups.com
Walter:
Personalmente considero que no funciona, pero me gustaría saber si al ejecutar, funciona.
¿Alguien puede hacerlo?
 
Gracias.

Walter R. Ojeda Valiente

unread,
May 6, 2013, 7:22:47 PM5/6/13
to sistemas-gestores...@googlegroups.com
En Firebird funciona, 100% seguro. Yo jamás escribo algo sobre lo que no estoy 100% seguro.

Saludos.

Walter.



2013/5/6 Hernan Cano <jherna...@gmail.com>

--
Has recibido este mensaje porque estás suscrito al grupo "Sistemas Gestores de Bases de Datos" de Grupos de Google.
Visita este grupo en http://groups.google.com/group/sistemas-gestores-de-bases-de-datos?hl=es-419.
 
 

Walter R. Ojeda Valiente

unread,
May 6, 2013, 7:23:48 PM5/6/13
to sistemas-gestores...@googlegroups.com
Pero como lo recalqué varias veces, cada uno de los SELECT internos debe devolver un valor y solamente un valor.

En otro caso por supuesto que no funcionará.

Saludos.

Walter.




2013/5/6 Walter R. Ojeda Valiente <woj...@gmail.com>

Martin Soto

unread,
May 6, 2013, 7:26:51 PM5/6/13
to sistemas-gestores...@googlegroups.com
No me funciona con el In, efectivamente se puede hacer un subquery ,
pero ya con 2 o mas separados por comas no.

Walter R. Ojeda Valiente

unread,
May 6, 2013, 7:39:05 PM5/6/13
to sistemas-gestores...@googlegroups.com
¿Estás seguro que cada uno de los SELECT internos te devuelve un valor y solamente un valor?

¿Estás seguro que cada uno de los SELECT internos está rodeado por paréntesis?

Si se cumplen ambas condiciones anteriores, en Firebird es 100% seguro que funciona.

Saludos.

Walter.





2013/5/6 Martin Soto <jmsro...@gmail.com>

Martin Soto

unread,
May 6, 2013, 8:00:09 PM5/6/13
to sistemas-gestores...@googlegroups.com
Que tal Walter

¿Estás seguro que cada uno de los SELECT internos te devuelve un valor
y solamente un valor?

A ver me supongo que esta instruccion es para identificar un valor de
un conjunto de registros, la instruccion efectivamente debe devolver
un campo, pero pueden ser multiples registros, si lo delimitas con
algun where articulo=100000, se pierde la magia de la instruccion, se
convierte en un simple in (100000,100001), asi que cual es el
proposito de usar un subquery.

La utilidad que le veo es decir de estos articulos cuantos estan en
tablapm o estan en tablapmy

SELECT * FROM articulos WHERE articulo IN ((SELECT codigo FROM
tablapm), (SELECT codigo FROM tablapmy))

estoy en sql server 2008 r2

regularmente esto lo hago en 2 pasos o con una tabla de paso, pero me
llama la atencion.

si puedes por favor publicar la instruccion que te funciona a ti.

saludos cordiales

Martin Soto


El día 6 de mayo de 2013 18:39, Walter R. Ojeda Valiente

Walter R. Ojeda Valiente

unread,
May 6, 2013, 8:15:15 PM5/6/13
to sistemas-gestores...@googlegroups.com
La utilidad del SELECT interno se ve cuando se obtiene un valor que se desconocía. Por ejemplo:

SELECT
   PRD_PREVTA
FROM
   PRODUCTOS
WHERE
   PRD_IDENTI = 123456

En este caso, se obtiene el Precio de Venta (cuyo valor era desconocido) consultando a la tabla de PRODUCTOS y buscando en ella al que tiene como identificador al número 123456.

Por lo tanto, respondiendo a tu pregunta, la utilidad de usar una subconsulta (subquery le llamaste) es obtener un valor desconocido (en el ejemplo: el precio de venta) partiendo de otro valor conocido (en el ejemplo: el identificador del producto).

Ahora, para aclarar las cosas: yo nunca dije que esta manera de consultar era la mejor, que era recomendable, que era buena, o algún otro adjetivo. Lo que hice fue responder una pregunta mostrando que sí era posible lograrlo, no toqué el tema de cuan eficiente es este método.

La frase anterior la escribí para que alguien no malentienda e interprete que yo recomiendo este método, espero que haya quedado claro. Lo que hice fue mostrar que sí es posible tener subconsultas dentro de un IN, solamente eso.

Saludos.

Walter.


Martin Soto

unread,
May 6, 2013, 8:34:44 PM5/6/13
to sistemas-gestores...@googlegroups.com
si te entiendo, en particular utilizo esta instruccion como utilitaria , cuando tengo un volumen fuerte de datos y se vuelve tedioso utilizar un In (xxxx,xxxx,xxxx,xxx,etc.)

ejemplo:

deseo saber cuantos articulos tengo ofertados


SELECT * FROM articulos WHERE articulo IN (SELECT articulo FROM precios WHERE boletin<>'')

resulta tambien valioso el NOT IN , asi como el exists.

saludos cordiales

Walter R. Ojeda Valiente

unread,
May 6, 2013, 8:41:56 PM5/6/13
to sistemas-gestores...@googlegroups.com
Ok, pero la pregunta que respondí es si se podía tener más de una subconsulta dentro de un IN y sí que se puede. Al menos en Firebird, aclaro, no lo he probado con otros SGBDR.

Saludos.

Walter.

Martin Soto

unread,
May 6, 2013, 8:52:00 PM5/6/13
to sistemas-gestores...@googlegroups.com
SI si es posible ejemplo
SELECT * FROM articulos WHERE articulo IN ((SELECT codigo FROM tablapm WHERE codigo=34876), (SELECT codigo FROM tablapmy WHERE codigo=34884))
lo que menciono es que se pierde mucho al hacer esto, por que en su caso para que colocar un select mejor lo hacemos de esta manera
SELECT * FROM articulos WHERE articulo IN (34876,34884)
lo que intento decir que si es posible pero a mi juicio no me parece una buena practica.

Walter R. Ojeda Valiente

unread,
May 6, 2013, 11:05:50 PM5/6/13
to sistemas-gestores...@googlegroups.com
Como te dije anteriormente, no tiene sentido escribir: SELECT codigo FROM tablapm WHERE codigo=34876

Lo que sí tiene sentido es escribir: SELECT nombre FROM tablapm WHERE codigo=34876

O SELECT prevta, o SELECT precto

O cualquier otro SELECT donde la columna consultada es distinta de la columna del WHERE.

Y si es buena práctica o no, pues habría que ver cuales son las distintas alternativas y luego verificar cual de todas ellas es la mejor.

Saludos.

Walter.

Reply all
Reply to author
Forward
0 new messages