【问题标题】:Doubling up on WHERE condition在 WHERE 条件下加倍
【发布时间】:2012-04-17 06:55:43
【问题描述】:

是否可以在 where 语句 @Age 参数中做类似这里发生的事情?

 @AGE Varchar(8)

 SELECT NAME FROM TABLE WHERE 
 (
 If @AGE='man'
  then (AGE = 'man' or AGE = 'boy')
  else (AGE = 'man')
 )
 AND City IS NULL

【问题讨论】:

  • AGE='man' OR (@AGE='MAN' and AGE='boy')?
  • @Damien_The_Unbeliever:我不认为它那么简单,例如考虑当@AGE = 'man'AGE = 'boy' OP 的搜索条件为真而你的搜索条件为假。 ——
  • @onedaywhen:为什么,这是真的。第一个比较产生 False,第二个和第三个产生 True。最后两者的合取也产生真,假和真的析取同样是真。
  • @AndriyM:不知道你说的第一、第二和第三是什么意思。对于我给出的案例中的值,If @AGE='man' then (AGE = 'man' or AGE = 'boy') 将评估为 TRUE,并且不会测试 ELSE 条件。
  • @AndriyM: ...我在答案中添加了一些测试代码。

标签: sql sql-server sql-server-2008


【解决方案1】:

是的,是这样的:

SELECT NAME FROM TABLE WHERE 
((@AGE='man'
   AND (AGE = 'man' or AGE = 'boy'))
OR
(@AGE <> 'man'
  AND (AGE = 'man')))
AND City IS NULL

注意条件@AGE &lt;&gt; 'man'可能需要根据@AGE 变量是否可以为空来调整。

我回答了一个非常相似的问题here

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

【讨论】:

    【解决方案2】:

    一种方法是使用EXEC 并通过If's 构建字符串命令。

    类似这样的:

    declare @t nvarchar(max)
    @AGE Varchar(8)
    set @t=' SELECT NAME FROM TABLE WHERE '
    
    
     If @AGE='man' set @t=@t+'(AGE = ''man'' or AGE = ''boy'')'
      else  set @t=@t+'(AGE = 'man')'
    
    set @t=@t+' AND City IS NULL'
    

    【讨论】:

      【解决方案3】:

      在合取范式中(“一系列与”,较少依赖于参数):

      SELECT * 
        FROM TABLE
       WHERE ( @AGE <> 'man' OR (AGE IN ('man', 'boy') ) )
             AND ( @AGE = 'man' OR AGE = 'man' )
             AND CITY IS NULL;
      

      这里的想法是使用蕴涵重写规则:

      ( IF x THEN y )  is equivalent to  ( NOT ( x ) OR y )
      

      这是一些测试代码:

      WITH T 
           AS
           (
            SELECT * 
              FROM (
                    VALUES (1, 'man', NULL), 
                           (2, 'boy', NULL), 
                           (3, 'girl', NULL)
                   ) AS T (NAME, AGE, CITY)
           ),
           Params
           AS
           (
            SELECT * 
              FROM (
                    VALUES ('man'), 
                           ('boy'), 
                           ('girl')
                   ) AS T (p_AGE)
           ), 
           Results
           AS
           (
            SELECT Params.*, T.*, 
                   CASE WHEN     ( ( p_AGE <> 'man' OR (AGE IN ('man', 'boy') ) ) AND ( p_AGE = 'man' OR AGE = 'man' ) )  THEN 'TRUE'
                        WHEN NOT ( ( p_AGE <> 'man' OR (AGE IN ('man', 'boy') ) ) AND ( p_AGE = 'man' OR AGE = 'man' ) )  THEN 'FALSE'
                        ELSE 'UNKNOWN' 
                   END AS result_onedaywhen, 
                   CASE WHEN     ( AGE='man' OR (p_AGE='MAN' and AGE='boy') )  THEN 'TRUE'
                        WHEN NOT ( AGE='man' OR (p_AGE='MAN' and AGE='boy') )  THEN 'FALSE'
                        ELSE 'UNKNOWN' 
                   END AS result_Damien_The_Unbeliever
              FROM T, Params
           )
      SELECT * 
        FROM Results;
      

      【讨论】:

        【解决方案4】:

        或者你可以使用decode functions

        【讨论】:

        • 问题被标记为sql-serverDECODE 在 SQL Server 上不存在。
        猜你喜欢
        • 2019-10-07
        • 2016-10-26
        • 2012-04-14
        • 1970-01-01
        • 1970-01-01
        • 2017-03-25
        • 2011-09-02
        • 2021-10-26
        • 1970-01-01
        相关资源
        最近更新 更多