【问题标题】:Conditional CASE/IF in constructing T-SQL statement构造 T-SQL 语句中的条件 CASE/IF
【发布时间】:2014-04-14 23:55:28
【问题描述】:

我在尝试转换为存储过程的前端代码中有一个查询。前端代码中有条件逻辑,可以根据表单值构造正确的 SQL。我没有编写原始 SQL,但我受命进行此转换。

我面临的问题是我没有足够的知识/经验去做这件事。我也咨询了这些链接以寻求帮助,但它们并没有完全让我到达那里:

SQL: conditional statement in GROUP BY clause

SQL Case statement specifiying condition in where clause?

伪代码:

WHERE b.ACTIVE=1
  AND YEAR(METRIC_YEAR) = @frmYear

IF @selOrg IS NOT NULL AND @selOrg != 'ALL'
     IF @selOrg = 'org1'
       AND ORG IN('org1','org2','org3') AND MEASURE_ID NOT IN(0,1,2,3,4)
     ELSE
       AND ORG = @selOrg
ELSE
     AND MEASURE_ID NOT IN(0,1,2,3,4)

尝试如此简单的操作会导致“END 附近的语法不正确”错误。

WHERE b.ACTIVE=1
  AND YEAR(METRIC_YEAR) = @frmYear
    AND
    CASE @selOrg 
    WHEN 'org1' THEN ORG IN('org1','org2','org3') AND MEASURE_ID NOT IN(0,1,2,3,4)
    END

我想做的事可能吗?如果是这样,我看不到什么?

【问题讨论】:

    标签: sql sql-server case


    【解决方案1】:

    你可以这样做:

    WHERE b.ACTIVE=1
    AND  YEAR(METRIC_YEAR) = @frmYear
    AND (
            (@selOrg = 'org1' AND ORG IN('org1','org2','org3') AND MEASURE_ID NOT IN(0,1,2,3,4))
        OR  (@selOrg = 'ALL')
        )
    

    取决于您的标准,尽管进行单独的查询可能是有益的 -

    IF @selOrg = 'org1'
        BEGIN 
            SELECT  ...
            FROM    Table
            WHERE b.ACTIVE=1
            AND  YEAR(METRIC_YEAR) = @frmYear   
            AND ORG IN('org1','org2','org3') 
            AND MEASURE_ID NOT IN(0,1,2,3,4);
        END
    ELSE IF @selOrg = 'All'
        BEGIN 
            SELECT  ...
            FROM    Table
            WHERE b.ACTIVE=1
            AND  YEAR(METRIC_YEAR) = @frmYear;
        END
    

    这可能看起来像是额外的工作,但您可能会得到更好的性能。

    【讨论】:

      【解决方案2】:

      “案例”示例

      SELECT   ProductNumber, Category =
            CASE ProductLine
               WHEN 'R' THEN 'Road'
               WHEN 'M' THEN 'Mountain'
               WHEN 'T' THEN 'Touring'
               WHEN 'S' THEN 'Other sale items'
               ELSE 'Not for sale'
            END,
         Name
      FROM Production.Product
      ORDER BY ProductNumber;
      

      SELECT   ProductNumber, Name, "Price Range" = 
            CASE 
               WHEN ListPrice =  0 THEN 'Mfg item - not for resale'
               WHEN ListPrice < 50 THEN 'Under $50'
               WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250'
               WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000'
               ELSE 'Over $1000'
            END
      FROM Production.Product
      ORDER BY ProductNumber ;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-07
        • 1970-01-01
        相关资源
        最近更新 更多