在where子句sql 2012中使用if语句或case语句

时间:2016-11-16 22:04:55

标签: sql sql-server sql-server-2012

我在SQL Server 2012中遇到过一种情况,我需要根据变量查询表中的其他列。所以我有一个表,列有一个bld_type字段和另外3个特定于年份的列。带有年份的列包含A或I. 因此表格就像这样设置

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'。

当我尝试将其放入另一个if构造时,摩擦就会出现。第一个例子会产生123,124。我需要做的是将代码添加到此if语句

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

换句话说,当我尝试在if语句中嵌入if语句时,它不想工作。我是否错过了一个支架或某种方式的结局?

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

我会将@TRM_type移动到where子句中,它应该更高效,然后只使用exists:

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的问题是如果你的内部查询可能产生Null,你将无法得到你想要的结果,因为SQL引擎不会如何解释(NULL)中的@var并返回所有内容。 Plus IN通常是SQL服务器(NOT IN vs NOT EXISTS

的最慢方法

至于将嵌入和IF语句嵌入到SQL 2012 plus的where子句中。它与控件IF不同,而是一个函数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表达最好。

关于嵌套IFs

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作为条件无法传递标量值来评估为真或假。

答案 1 :(得分: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