Principales respuestas
Sentencia SQL con un If

Pregunta
-
Buen día.
Estoy trabajando en un Procedimiento Almacenado, el cual tiene la función de buscar unos datos por un rango de fechas y otras variables. Estas otras variables son opciones, solo el rango de fechas es obligatoria.
Entonces tengo un Select sencillo:
select *
from tabla1 inner join tabla2 on tabla1.codigo = tabla2.codTabla1
where tabla1.fecha between '20180112 00:00:00' and '20180112 23:59:59'
Lo que necesito saber es si yo puedo agregar un If o algo que me permita agregarle otra sentencia al Where si la variable tiene datos o no, por ejemplo:
select *
from tabla1 inner join tabla2 on tabla1.codigo = tabla2.codTabla1
where tabla1.fecha between '20180112 00:00:00' and '20180112 23:59:59'
if (@variable = '') Begin
and tabla1.Anulado = 'N'
end
else begin
and tabla1.Anulado = 'S'
end
Espero haberme dado a entender y de antemano gracias por la ayuda que me puedan dar.
Respuestas
-
Es posible realizar la validación que mencionas con algunos cambios de sintaxis en la expresión:
SELECT * FROM tabla1 INNER JOIN tabla2 ON tabla1.codigo = tabla2.codTabla1 WHERE tabla1.fecha BETWEEN '20180112 00:00:00' AND '20180112 23:59:59' AND ((tabla1.Anulado = 'N' AND @variable = '') OR (tabla1.Anulado = 'S' AND @variable <> '')); GO
- Propuesto como respuesta Pablo RubioModerator viernes, 12 de enero de 2018 19:55
- Marcado como respuesta Pablo RubioModerator lunes, 15 de enero de 2018 16:15
-
Esa es una alternativa fácil de programar pero considero que es algo peligrosa a la hora del rendimiento ya que si esto se hace más complejo que dos o tres alternativas de condiciones opcionales suele suceder que el planificador termina eligiendo planes ineficientes cuando hay muchas condiciones OR y termina haciendo un TABLE SCAN.
Yo sugiero usar IF
IF @condicion is not null BEGIN --consulta completa con @condicion agregada END ELSE BEGIN -- Consulta completa sin @condicion agregada END
Es mucho más trabajoso pero conozco a alguien que se tomó el trabajo de armar un programita que generaba todas las 2^N combinaciones (N son las condicioenes opcionales). Lo hizo mediante un árbol binario y recursión.
Otra alternativa es usar código dinámico que solo tiene un pequeño costo adicional de CPU en la compilación que para el caso habitual de los reportes no es significativo (si fuera algo que se ejecuta millones de veces es mucho mejor el IF) y permite al planificador usar un plan más adecuado.
Saludos
Ing. Jose Mariano Alvarez - http://blog.josemarianoalvarez.com
- Propuesto como respuesta Pablo RubioModerator viernes, 12 de enero de 2018 19:55
- Marcado como respuesta Pablo RubioModerator lunes, 15 de enero de 2018 16:15
-
Hola, podrias utilizar un case en el where,algo como
create table #pruebas ( id int identity(1,1), nombre varchar(100), fecha datetime, anulado char(1) ) insert into #pruebas (nombre,fecha,anulado) values ('eduardo', getdate(),'s') insert into #pruebas (nombre,fecha,anulado) values ('jose', getdate(),'s') insert into #pruebas (nombre,fecha,anulado) values ('luis', getdate(),'n') declare @VARIABLE as varchar(10) set @VARIABLE='' select * from #pruebas where anulado= case @VARIABLE when '' then 's' else 'n' end set @VARIABLE='algo' select * from #pruebas where anulado= case @VARIABLE when '' then 's' else 'n' end drop table #pruebas
select * from tabla1 inner join tabla2 on tabla1.codigo = tabla2.codTabla1 where tabla1.fecha between '20180112 00:00:00' and '20180112 23:59:59' and tabla1.Anulado= case @VARIABLE when '' then 'N' else 'S' end
Votar es agradecer.
Saludos.
Lima-Perú
- Editado Augusto1982 viernes, 12 de enero de 2018 15:50
- Propuesto como respuesta Pablo RubioModerator viernes, 12 de enero de 2018 19:55
- Marcado como respuesta Pablo RubioModerator lunes, 15 de enero de 2018 16:15
Todas las respuestas
-
Es posible realizar la validación que mencionas con algunos cambios de sintaxis en la expresión:
SELECT * FROM tabla1 INNER JOIN tabla2 ON tabla1.codigo = tabla2.codTabla1 WHERE tabla1.fecha BETWEEN '20180112 00:00:00' AND '20180112 23:59:59' AND ((tabla1.Anulado = 'N' AND @variable = '') OR (tabla1.Anulado = 'S' AND @variable <> '')); GO
- Propuesto como respuesta Pablo RubioModerator viernes, 12 de enero de 2018 19:55
- Marcado como respuesta Pablo RubioModerator lunes, 15 de enero de 2018 16:15
-
Hola, podrias utilizar un case en el where,algo como
create table #pruebas ( id int identity(1,1), nombre varchar(100), fecha datetime, anulado char(1) ) insert into #pruebas (nombre,fecha,anulado) values ('eduardo', getdate(),'s') insert into #pruebas (nombre,fecha,anulado) values ('jose', getdate(),'s') insert into #pruebas (nombre,fecha,anulado) values ('luis', getdate(),'n') declare @VARIABLE as varchar(10) set @VARIABLE='' select * from #pruebas where anulado= case @VARIABLE when '' then 's' else 'n' end set @VARIABLE='algo' select * from #pruebas where anulado= case @VARIABLE when '' then 's' else 'n' end drop table #pruebas
select * from tabla1 inner join tabla2 on tabla1.codigo = tabla2.codTabla1 where tabla1.fecha between '20180112 00:00:00' and '20180112 23:59:59' and tabla1.Anulado= case @VARIABLE when '' then 'N' else 'S' end
Votar es agradecer.
Saludos.
Lima-Perú
- Editado Augusto1982 viernes, 12 de enero de 2018 15:50
- Propuesto como respuesta Pablo RubioModerator viernes, 12 de enero de 2018 19:55
- Marcado como respuesta Pablo RubioModerator lunes, 15 de enero de 2018 16:15
-
-
-
Esa es una alternativa fácil de programar pero considero que es algo peligrosa a la hora del rendimiento ya que si esto se hace más complejo que dos o tres alternativas de condiciones opcionales suele suceder que el planificador termina eligiendo planes ineficientes cuando hay muchas condiciones OR y termina haciendo un TABLE SCAN.
Yo sugiero usar IF
IF @condicion is not null BEGIN --consulta completa con @condicion agregada END ELSE BEGIN -- Consulta completa sin @condicion agregada END
Es mucho más trabajoso pero conozco a alguien que se tomó el trabajo de armar un programita que generaba todas las 2^N combinaciones (N son las condicioenes opcionales). Lo hizo mediante un árbol binario y recursión.
Otra alternativa es usar código dinámico que solo tiene un pequeño costo adicional de CPU en la compilación que para el caso habitual de los reportes no es significativo (si fuera algo que se ejecuta millones de veces es mucho mejor el IF) y permite al planificador usar un plan más adecuado.
Saludos
Ing. Jose Mariano Alvarez - http://blog.josemarianoalvarez.com
- Propuesto como respuesta Pablo RubioModerator viernes, 12 de enero de 2018 19:55
- Marcado como respuesta Pablo RubioModerator lunes, 15 de enero de 2018 16:15