SQL:WHERE子句中的IF子句

时间:2008-09-17 21:24:49

标签: sql sql-server tsql

是否可以在MS SQL的 WHERE 子句中使用 IF 子句?

示例:

WHERE
    IF IsNumeric(@OrderNumber) = 1
        OrderNumber = @OrderNumber
    ELSE
        OrderNumber LIKE '%' + @OrderNumber + '%'

16 个答案:

答案 0 :(得分:191)

使用CASE声明
更新:以前的语法(由少数人指出)不起作用。您可以按如下方式使用CASE:

WHERE OrderNumber LIKE
  CASE WHEN IsNumeric(@OrderNumber) = 1 THEN 
    @OrderNumber 
  ELSE
    '%' + @OrderNumber
  END

或者您可以使用@ N. J. Reed等IF语句指出。

答案 1 :(得分:126)

你应该可以在没有任何IF或CASE的情况下做到这一点

 WHERE 
   (IsNumeric(@OrderNumber) AND
      (CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
 OR
   (NOT IsNumeric(@OrderNumber) AND
       OrderNumber LIKE ('%' + @OrderNumber))

根据SQL的风格,您可能需要将订单号上的强制转换调整为INT或VARCHAR,具体取决于是否支持隐式强制转换。

这是WHERE子句中非常常见的技术。如果你想在WHERE子句中应用一些“IF”逻辑,你需要做的就是将一个带有布尔AND的额外条件添加到需要应用它的部分。

答案 2 :(得分:19)

根本不需要IF语句。

WHERE
    (IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')

答案 3 :(得分:13)

在SQL中没有一种好方法可以做到这一点。我见过的一些方法:

1)使用CASE结合布尔运算符:

WHERE
    OrderNumber = CASE 
        WHEN (IsNumeric(@OrderNumber) = 1)
        THEN CONVERT(INT, @OrderNumber)
        ELSE -9999 -- Some numeric value that just cannot exist in the column
    END
    OR 
    FirstName LIKE CASE
        WHEN (IsNumeric(@OrderNumber) = 0)
        THEN '%' + @OrderNumber
        ELSE ''
    END

2)在SELECT

之外使用IF
IF (IsNumeric(@OrderNumber)) = 1
BEGIN
    SELECT * FROM Table
    WHERE @OrderNumber = OrderNumber
END ELSE BEGIN
    SELECT * FROM Table
    WHERE OrderNumber LIKE '%' + @OrderNumber
END

3)使用长字符串,有条件地编写SQL语句,然后使用EXEC

第三种方法很可怕,但如果你有许多可变条件,它几乎是唯一可行的方法。

答案 4 :(得分:6)

使用CASE语句代替IF。

答案 5 :(得分:4)

您需要CASE声明

WHERE OrderNumber LIKE
CASE WHEN IsNumeric(@OrderNumber)=1 THEN @OrderNumber ELSE '%' + @OrderNumber END

答案 6 :(得分:3)

我认为那里......喜欢/ = ......案例......那么......可以和布尔人一起工作。我正在使用T-SQL。

场景:如果bool是假的话,假设你想要获得Person-30的爱好,如果bool是真的,那么Person-42的爱好。 (据一些人说,业余爱好查找包含超过90%的业务计算周期,所以要特别关注。)。

CREATE PROCEDURE sp_Case
@bool   bit
AS
SELECT Person.Hobbies
FROM Person
WHERE Person.ID = 
    case @bool 
        when 0 
            then 30
        when 1
            then 42
    end;

答案 7 :(得分:1)

WHERE (IsNumeric(@OrderNumber) <> 1 OR OrderNumber = @OrderNumber) 
             AND (IsNumber(@OrderNumber) = 1 OR OrderNumber LIKE '%' 
                                              + @OrderNumber + '%')

答案 8 :(得分:0)

以下示例将查询作为布尔表达式的一部分执行,然后根据布尔表达式的结果执行稍微不同的语句块。每个语句块以BEGIN开头,以END结束。

USE AdventureWorks2012;
GO
DECLARE @AvgWeight decimal(8,2), @BikeCount int
IF 
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
BEGIN
   SET @BikeCount = 
        (SELECT COUNT(*) 
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%');
   SET @AvgWeight = 
        (SELECT AVG(Weight) 
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%');
   PRINT 'There are ' + CAST(@BikeCount AS varchar(3)) + ' Touring-3000 bikes.'
   PRINT 'The average weight of the top 5 Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.';
END
ELSE 
BEGIN
SET @AvgWeight = 
        (SELECT AVG(Weight)
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%' );
   PRINT 'Average weight of the Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.' ;
END ;
GO

使用嵌套的IF ... ELSE语句 以下示例显示了IF ... ELSE语句如何嵌套在另一个语句中。将@Number变量设置为5,50和500以测试每个语句。

DECLARE @Number int
SET @Number = 50
IF @Number > 100
   PRINT 'The number is large.'
ELSE 
   BEGIN
      IF @Number < 10
      PRINT 'The number is small'
   ELSE
      PRINT 'The number is medium'
   END ;
GO

答案 9 :(得分:0)

  

CASE 语句总是比 IF 更好的选择。

print(instance.text)

答案 10 :(得分:0)

    WHERE OrderNumber LIKE CASE WHEN IsNumeric(@OrderNumber) = 1 THEN @OrderNumber ELSE  '%' + @OrderNumber END

在适当情况下,条件将正常工作。

答案 11 :(得分:0)

在sql server中,我有一个同样的问题,我只想在参数为false时使用and语句,并且在true时必须同时显示true和false值,所以我以这种方式使用了

(T.IsPublic = @ShowPublic or  @ShowPublic = 1)

答案 12 :(得分:0)

// 使用存储过程选择按国家和站点过滤的用户的示例

CREATE STORED PROCEDURE GetUsers
@CountryId int = null,
@SiteId int = null
AS
BEGIN
SELECT *
        FROM users 
        WHERE
                CountryId  = CASE WHEN ISNUMERIC(@CountryId) = 1 THEN @CountryId ELSE CountryId END AND
                SiteId     = CASE WHEN ISNUMERIC(@SiteId) = 1 THEN @SiteId ELSE SiteId END;

结束

答案 13 :(得分:0)

澄清一些逻辑等价解决方案。

if 语句

if (a) then b

在逻辑上等价于

(!a || b)

它是 Logical equivalence wikipedia article涉及条件语句的逻辑等价部分的第一行。

要包含else,您只需添加另一个条件

if(a) then b; 
if(!a) then c;

这在逻辑上等价于 (!a || b) && (a || c)

所以以 OP 为例:

IF IsNumeric(@OrderNumber) = 1
    OrderNumber = @OrderNumber
ELSE
    OrderNumber LIKE '%' + @OrderNumber + '%'

逻辑等价物是:

(IsNumeric(@OrderNumber) <> 1 OR OrderNumber = @OrderNumber)
AND (IsNumeric(@OrderNumber) = 1 OR OrderNumber LIKE '%' + @OrderNumber + '%' )

答案 14 :(得分:-1)

If @LstTransDt is Null
                begin
                    Set @OpenQty=0
                end
            else
                begin
                   Select   @OpenQty=IsNull(Sum(ClosingQty),0)  
                   From  ProductAndDepotWiseMonitoring  
                   Where   Pcd=@PCd And PtpCd=@PTpCd And TransDt=@LstTransDt      
                end 

看看这是否有帮助。

答案 15 :(得分:-6)

USE AdventureWorks2012;
GO
IF 
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
PRINT 'There are more than 5 Touring-3000 bicycles.'
ELSE PRINT 'There are 5 or less Touring-3000 bicycles.' ;
GO