sql - SQL Server 2008 中 "CASE"子句内的 "WHERE"语句

标签 sql sql-server case

我正在处理一个在“WHERE”子句中包含“CASE”语句的查询。但 SQL Server 2008 在执行时出现一些错误。谁能帮我正确的查询吗?这是查询:

SELECT
    tl.storenum 'Store #', 
    co.ccnum 'FuelFirst Card #', 
    co.dtentered 'Date Entered',
    CASE st.reasonid 
        WHEN 1 THEN 'Active' 
   WHEN 2 THEN 'Not Active' 
   WHEN 0 THEN st.ccstatustypename 
   ELSE 'Unknown' 
    END 'Status',
    CASE st.ccstatustypename 
        WHEN 'Active' THEN ' ' 
   WHEN 'Not Active' THEN ' ' 
   ELSE st.ccstatustypename 
    END 'Reason',
    UPPER(REPLACE(REPLACE(co.personentered,'RT\\\\',''),'RACETRAC\\\\','')) 'Person Entered',
    co.comments 'Comments or Notes'
FROM 
    comments co
    INNER JOIN cards cc ON co.ccnum=cc.ccnum
    INNER JOIN customerinfo ci ON cc.customerinfoid=ci.customerinfoid
    INNER JOIN ccstatustype st ON st.ccstatustypeid=cc.ccstatustypeid
    INNER JOIN customerstatus cs ON cs.customerstatuscd=ci.customerstatuscd
    INNER JOIN transactionlog tl ON tl.transactionlogid=co.transactionlogid
    LEFT JOIN stores s ON s.StoreNum = tl.StoreNum
WHERE 
    CASE LEN('TestPerson')
        WHEN 0 THEN co.personentered  = co.personentered
   ELSE co.personentered LIKE '%TestPerson'
    END 
    AND cc.ccnum = CASE LEN('TestFFNum')
        WHEN 0 THEN cc.ccnum 
   ELSE 'TestFFNum' 
    END 
    AND CASE LEN('2011-01-09 11:56:29.327') 
        WHEN 0 THEN co.DTEntered = co.DTEntered 
   ELSE 
       CASE LEN('2012-01-09 11:56:29.327') 
           WHEN 0 THEN co.DTEntered >= '2011-01-09 11:56:29.327' 
      ELSE co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327' 
       END 
    END
    AND tl.storenum < 699 
ORDER BY tl.StoreNum

最佳答案

首先,CASE 语句必须是表达式的一部分,而不是表达式本身。

换句话说,您可以:

WHERE co.DTEntered = CASE 
                          WHEN LEN('blah') = 0 
                               THEN co.DTEntered 
                          ELSE '2011-01-01' 
                     END 

但是它不会像你写的那样工作,例如:

WHERE 
    CASE LEN('TestPerson')
        WHEN 0 THEN co.personentered  = co.personentered
   ELSE co.personentered LIKE '%TestPerson'
    END 

使用如下组合 OR 语句可能会有更好的运气:

WHERE (
        (LEN('TestPerson') = 0 
             AND co.personentered = co.personentered
        ) 
        OR 
        (LEN('TestPerson') <> 0 
             AND co.personentered LIKE '%TestPerson')
      )

尽管如此,我不确定您会得到多好的查询计划。 WHERE 子句中的这些类型的恶作剧通常会阻止查询优化器利用索引。

关于sql - SQL Server 2008 中 "CASE"子句内的 "WHERE"语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8785209/

相关文章:

MySQL:来自另一个表列的列的默认值

sql - 使用时间跨度对具有相同值的连续行进行分组

c++ - 关于 'case'中 'switch'语句中的大括号

linux - 在 bash 中的位置参数中添加秒选项

sql - 复杂的组SQL查询

c# - 为什么 SqlQuery 比在 View 上使用 LINQ 表达式快很多?

MySQL 每次的行数

sql-server - 使用动态 T-SQL 将数据类型 nvarchar 转换为 float 时出错

c# - 如何将多个数据库值返回到文本框?

case - CRM 2011 - 使用案例表单上的联系数据