FTP | CCD | Buscar | Trucos | Trabajo | Foros |
#1
|
|||
|
|||
Consulta - MSSQL
Buenas, estoy algo mareado y no encuentro la vuelta a esta consulta
Trabajo con MSSQL Tengo una tabla X que tiene los campos: Fecha, IdAccion .... Y otra tabla Y donde tengo : Permitido(bit) , IdAccion..... Lo que tengo que obtener son todos los registros de la tabla X que correspondan al dia de hoy, SI no existe otro reg del dia de hoy donde Permitido(haciendo un Inner join con Tabla Y) sea 0. Lo primero es facil Select * From TablaX Where (datepart(dy,fecha)=datepart(dy,getdate())) Pero no encuentro la forma de ver que no exista otro registro sin permiso para el mismo dia. Alguna idea???? Muchas Gracias por su tiempo.
__________________
Marín Ignacio Borthiry (Viet) - "El hombre arriesga su vida cada vez que elije y eso es lo que lo hace libre" ;) |
#2
|
|||
|
|||
Lo unico que se me ocurre es una subconsulta en el Where con :
Código:
Select * From TablaX Where (datepart(dy,fecha)=datepart(dy,getdate())) and Id not in(select * from tablaX x inner join tablaY y on (x.IdAccion=y.IdAccion) where y.Permitido=0 and (clausela de fecha) ) Algo mas simple?
__________________
Marín Ignacio Borthiry (Viet) - "El hombre arriesga su vida cada vez que elije y eso es lo que lo hace libre" ;) Última edición por Viet fecha: 08-10-2003 a las 21:07:25. |
#3
|
||||
|
||||
Hola.
¿ Que es lo malo de : ? Código:
Select X.* From X left outer join Y on X.IdAccion = Y.IdAccion Where datepart(dy, X.Fecha)=datepart(dy, getdate())) and Y.Permitido is null or Y.Permitido = 0 Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no). |
#4
|
||||
|
||||
Yo preferiría usar un NOT EXISTS, que según el motor (Desconozco lo que hace en MsSql) cuando encuentra al menos un registro deja cancela la subconsulta:
Código:
SELECT * FROM TABLAX WHERE datepart(dy,fecha)=datepart(dy,getdate()) AND NOT EXISTS (SELECT 1 FROM TABLAY AND TABLAX.IDACCION = TABLAY.IDACCION ...) Saludos!
__________________
delphi.com.ar Dedique el tiempo suficiente para formular su pregunta si pretende que alguien dedique su tiempo en contestarla. |
#5
|
|||
|
|||
Perdón ... no me he explicado bien...
Aclaracion ID no es clave de la tabla(solo es FK) Ej tabla X id IDAccion (omito fecha y los demas) 1 1 2 3 3 1 1 2 3 3 2 1 Tabla y IdAccion Permitido 1 1 2 0 1 1 Solo tendria que darme id 2 3 3 2 Osea solo tengo que mostrar los que no tienen en la otra tabla no permitido..... Se entiende la diferencia ?
__________________
Marín Ignacio Borthiry (Viet) - "El hombre arriesga su vida cada vez que elije y eso es lo que lo hace libre" ;) |
#6
|
|||
|
|||
Gracias por el dato Delphi.com.ar
Perdon Marc... si quise decir clausula
__________________
Marín Ignacio Borthiry (Viet) - "El hombre arriesga su vida cada vez que elije y eso es lo que lo hace libre" ;) |
#7
|
||||
|
||||
Hola Viet.
Cita:
Por cierto, por lo que comentas en el ultimo mensaje, la consulta que he propuesto debería servirte. Devuelve todas las filas de la tabla X del dia solicitado, que no tengan un registro relacionado en la tabla Y marcado como Permitido = 1. Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no). |
#8
|
||||
|
||||
Creo que solo habría que añadirle la clausula distinct al select, para que devuelva el resultado que pedias en el ejemplo.
Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no). |
#9
|
|||
|
|||
Marc si agrega la clausula me daria
id 2 3 Y necesito id 2 3 3 2 y el problema es que no solo necesito el id, sino otra informacion asociada fecha, posicion, evento, y unos cuantos campos que necesito de esta consulta.... De todo modos muchas gracias ...... Ahora bien ..... se me ocurre que podria hacer la consulta en una tabla temporal y luego borrar los registros que tengan permitido en 0... pero creo que estoy en la misma... no?
__________________
Marín Ignacio Borthiry (Viet) - "El hombre arriesga su vida cada vez que elije y eso es lo que lo hace libre" ;) |
#10
|
||||
|
||||
Hola.
Solo te quedaría eso si unicamente tuvieras select distinct id from .... Pero no con un select distinct X.* from ..., Puesto que también se selecciona la clave primaria de X, por lo que si tenemos dos registros con el mismo IdAccion, aparecerá dos veces incluso con el Distinct (debido a que la clave primaria al menos, será distinta). El distinct lo ponemos, por si hay dos registros relacionados en Y, al hacernos la unión, no nos devuelva dos veces el mismo registro de X. Realmente me gustaria que probases esta consulta, a ver si es lo que buscavas, o ver que problema debemos arreglar en ella : Código:
Select distinct X.* From X left outer join Y on X.IdAccion = Y.IdAccion Where datepart(dy, X.Fecha)=datepart(dy, getdate())) and Y.Permitido is null or Y.Permitido = 0
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no). |
#11
|
|||
|
|||
Marc: desde ya muchas gracias por tu tiempo.
te cuento: obviamente que he supuesto la tabla X e Y ya que las originales son algo complicadas o mejor dicho largo de poner.... y no lo he probado antes ya que estoy manejando una cantidad de mas o menos 1.500.000 registros..... aunque no es excusa bien... la consulta con la subconsulta me funciona bien(aunque no he logrado hacer funcionar el EXISTS que Delphi.com.ar me recomendo, no lo reconoce, y es MSSQL 7 ?? raro ... en fin) Pero al poner la query con el left outter join no me devuelve ningun registro lo que seria X.* , en realidad son varios campos , con una que otra funcion como dateadd y otros ..... puede ser por eso????
__________________
Marín Ignacio Borthiry (Viet) - "El hombre arriesga su vida cada vez que elije y eso es lo que lo hace libre" ;) |
#12
|
||||
|
||||
Hola
Tampoco habia usado nunca el EXISTS, lo he mirado un poco en la documentación del MSSQL y me parece muy curiosa su sintaxis (La verdad es que no acabo de entenderla, no se indican los campos a comparar). Es bastante más comprensible el operador relacionado ANY. Mirandolo bien, no creo que puedas usar el LEFT OUTER JOIN. Si la tabla relacionada (la Y) puede tener varios registros relacionados con la maestra X, y algunos de ellos marcan la operación como permitida y otras como no permitida, entonces el LEFT OUTER JOIN nos va a dejar pasar los registros de esa operación en X, puesto que cumplirán la condición cuando la unión se realize con los registros marcados como permitidos en Y. Me parece que la única alternativa es utilizar una subconsulta, aunque puede ser un poco más sencilla de la que proponias : Código:
Select * From X Where datepart(dy, Fecha) = datepart(dy, getdate()) and IdAccion not in (select IdAccion from Y where Permitido = 0) Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no). Última edición por guillotmarc fecha: 08-10-2003 a las 22:02:04. |
#13
|
|||
|
|||
Es lo que suponia Marc.... en realidad queda la consulta que tenia(la que tiene la subconsulta),.... ya que los registros que hay que filtrar son los que estan en la tabla X y que tengan alguno relacionado con Y que de Permitido=0...osea lo que estamos hablando....
Pregunta code:-------------------------------------------------------------------------------- Select * From X Where datepart(dy, Fecha) = datepart(dy, getdate()) and IdAccion not in (select IdAccion from Y where Permitido = 0) -------------------------------------------------------------------------------- no es lo mismo que Código:
Select * From X inner join Y on (y.idaccion=x.idaccion) where datepart(dy, Fecha) = datepart(dy, getdate())
__________________
Marín Ignacio Borthiry (Viet) - "El hombre arriesga su vida cada vez que elije y eso es lo que lo hace libre" ;) |
#14
|
||||
|
||||
Hola.
No es lo mismo, el resultado va a ser bastante distinto. Un Inner Join es una unión, por lo que solo te va a coger los registros de X que tengan registros relacionados en Y. Además si tienes dos registros en Y relacionados con uno de X, en el resultado vas a tener dos veces el registro de X. Esos dos registros de salida, se evaluan una vez uniendolo con el primer registro relacionado de Y, y la otra vez con el segundo. De forma que si el primer registro de Y permite la operación, vas a tener el registro X en la salida (independientemente de que el segundo registro de Y no permita la operación). Según lo tengo entendido, solo con que uno cualquiera de los registros relacionados en Y no permita la operación, ya no debes poder seleccionar el registro de X. Eso es lo que hace la consulta con subconsulta que he puesto. Para empezar evalua todos los registros de X una sola vez (tengan uno, dos, o ningún registro relacionado en Y). Y para cada uno de los registros de X, comprueba de que no exista algún registro relacionado en Y donde lo marca como no Permitido (con que solo haya uno, ya falla la condición y no se selecciona el registro de X). Espero que se entienda algo de lo que he escrito (es que no veo una forma mejor de explicarlo). A ver si esta consulta hace lo que necesitas, sino es que no he entendido bien lo que debe ejecutar la consulta. Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no). |
#15
|
|||
|
|||
Esta muy claro Marc, y tienes toda la razon: no son resultados ni remotamente parecidas......
Lo que pasa es que en mi caso todos los registros de X tienen solo uno en Y.... osea que X.IdAccion es FK de Y.IdAccion que es Pk, por lo que el resultado si seria el mismo(va a esta altura no estoy seguro , je!)..... Todo esto pasa por que no he planteado el problema como es realmente, eso lo he hecho para tratar de eliminar de este Thread toda la complejidad de las tablas que manejo... lo cual me ha resultado en contra y le he hecho tipear y pensar mas de lo debido.... Moraleja: "Hay que plantear bien todas las consultas, en forma concisa pero dando los detalles del caso..... y no resumir las variables del problema". Muchas Gracias por todo .... un Saludo
__________________
Marín Ignacio Borthiry (Viet) - "El hombre arriesga su vida cada vez que elije y eso es lo que lo hace libre" ;) |
Herramientas | Buscar en Tema |
Desplegado | |
|
|
|