2016-11-16 239 views
0

我在SQL Server 2012中遇到了一种情况,我需要根据变量查询表中的不同列。所以我有一个表格,列中有一个bld_type字段和3个特定于年份的附加列。与去年列包含一个a或I
所以表中设置这样在where子句中使用if语句或case语句sql 2012

TestTable的

bld_type bld_2015 bld_2016 bld_2017 
123   A  A  I 
124   A  A  I 
126   I  A  I 

我有一个要比较一个变量,我从得到一个存储过程基于项目生产年份的bld_type的外部来源。

我试过if year = 2015 then select bld_type from testtable where bld_2015 = 'A' ,这工作正常,我甚至说其他和有不同的选择语句检查bld_2016 ='A'。

当我尝试把它放入另一个构造中时,就会出现这种情况。第一个例子将产生123,124。而我需要做的是,如果声明

if @TRM_type not in (my code from above) 
begin @errorcount = @errorcount + 1 end 

的代码添加到该换句话说,当我尝试if语句嵌入内部的if语句它不想工作。我是否以某种方式丢失了一个括号或结尾?

在此先感谢您的帮助。

+0

我们需要看到您的代码有任何帮助您的机会。如果您要发布表格数据,则需要对其进行格式化,以便我们可以对其进行解码。你的问题的标题表明存在一个主要问题,因为你不能把一个if语句放在where子句中。 –

回答

0

我讨厌在WHERE子句中使用CASE语句,但是这应该为您提供所需的构建类型。

SELECT bld_type FROM testtable WHERE (CASE @year WHEN 2015 THEN bld_2015 
               WHEN 2016 THEN bld_2016 
               WHEN 2017 THEN bld_2017 
               ELSE NULL END) = 'A' 

则...

if @TRM_type not in (SELECT bld_type 
         FROM testtable 
         WHERE (CASE @year WHEN 2015 THEN bld_2015 
             WHEN 2016 THEN bld_2016 
             WHEN 2017 THEN bld_2017 
             ELSE NULL END) = 'A') 
begin @errorcount = @errorcount + 1 end 
1

我将在@TRM_type移动到WHERE子句以及它应该是更好的性能,然后只用存在:

IF NOT EXISTS (
    SELECT 
     1 
    FROM 
     TestTable 
    WHERE 
     CASE @year 
      WHEN 2015 THEN bld_2015 
      WHEN 2016 THEN bld_2016 
      WHEN 2017 THEN bld_2017 
     END = 'A' 
     AND bld_type = @TRM_type 
) 
BEGIN 
    SET @errorcount = @errorcount + 1 
END 

问题与IN是如果你的内部查询可能会产生一个空你不会得到你想要的结果作为SQL引擎不会如何解释@var(NULL)并将返回一切。 Plus IN通常是SQL服务器最慢的方法(NOT IN vs NOT EXISTS

就嵌入和IF语句插入到SQL 2012的where子句加上。它是不一样的控制相反,如果它是一个功能IIF(condition, true, false)https://msdn.microsoft.com/en-us/library/hh213574.aspx 所以要“嵌入它”或者更确切地说,用它在查询中,你会做这样的事情:

SELECT * 
FROM 
    testtable 
WHERE 
    IIF(@year = 2016, bld_2016, NULL) = 'A' 

但因为你有一个以上2例(2015,206,2017)CASE表达最好。

而关于嵌套的IF

IF (condition - Scalar Value That Evaluates to True) 
BEGIN 

    IF (Condition) 
    BEGIN 
     --Do Something 
    END 

END 

但是这样你可以巢IF的:

IF (IF BEGIN do something END) 
BEGIN 

END 

其中一个原因是因为IF的条件没​​有传递方式标量值来评估为真或假。