SQL Server 2008中“WHERE”子句中的“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陈述必须是expression的一部分 ,而不是expression本身。

换句话说,你可以有:

 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子句中的这些forms通常会阻止查询优化器使用索引。

这应该暂时解决你的问题,但我必须提醒你,这不是一个好方法:

 WHERE CASE LEN('TestPerson') WHEN 0 THEN CASE WHEN co.personentered = co.personentered THEN 1 ELSE 0 END ELSE CASE WHEN co.personentered LIKE '%TestPerson' THEN 1 ELSE 0 END END = 1 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 CASE WHEN co.DTEntered = co.DTEntered THEN 1 ELSE 0 END ELSE CASE LEN('2012-01-09 11:56:29.327') WHEN 0 THEN CASE WHEN co.DTEntered >= '2011-01-09 11:56:29.327' THEN 1 ELSE 0 END ELSE CASE WHEN co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327' THEN 1 ELSE 0 END END END = 1 AND tl.storenum < 699 

尝试以下操作:

 select * From emp_master where emp_last_name= case emp_first_name when 'test' then 'test' when 'Mr name' then 'name' end 

我认为你的查询的开始应该是这样的:

 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 WHEN (LEN([TestPerson]) = 0 AND co.personentered = co.personentered) OR (LEN([TestPerson]) <> 0 AND co.personentered LIKE '%'+TestPerson) THEN 1 ELSE 0 END = 1 AND 

尾巴里的东西是完全不可理解的

WHERE可以这样写:

 WHERE (LEN('TestPerson') <> 0 OR co.personentered = co.personentered) AND (LEN('TestPerson') = 0 OR co.personentered LIKE '%TestPerson') AND (cc.ccnum = CASE LEN('TestFFNum') WHEN 0 THEN cc.ccnum ELSE 'TestFFNum' END ) AND (LEN('2011-01-09 11:56:29.327') <> 0 OR co.DTEntered = co.DTEntered ) AND ((LEN('2011-01-09 11:56:29.327') = 0 AND LEN('2012-01-09 11:56:29.327') <> 0) OR co.DTEntered >= '2011-01-09 11:56:29.327' ) AND ((LEN('2011-01-09 11:56:29.327') = 0 AND LEN('2012-01-09 11:56:29.327') = 0) OR co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327' ) AND tl.storenum < 699 

这是我的解决scheme

 AND CLI.PE_NOM Like '%' + ISNULL(@NomClient, CLI.PE_NOM) + '%' 

Registers Davy

这工作

 declare @v int=A select * from Table_Name where XYZ=202 and dbkey=(case @v when A then 'Some Value 1' else 'Some Value 2' end) 
 select TUM1.userid,TUM1.first_name + ' ' +TUM1.last_name as NAME,tum1.Business_Title,TUM1.manager_id,tum2.First_Name + ' ' + tum2.Last_Name as [MANAGER NAME],TUM1.project,TUM1.project_code,TUM1.rcc_code,TUM1.department,TCM.Company_Name, case when tum1.Gender_ID=1 then 'male' else 'female' end 'GENDER' ,tum1.Band as BAND, case when tum1.Inactive=0 then 'STILL IN COMPANY' else 'LEFT COMPANY' end 'ACTIVE/INACTIVE' from tbl_user_master TUM1 join tbl_Company_Master TCM on TCM.Company_Code=TUM1.Company_Code join tbl_User_Master TUM2 on TUM1.Manager_ID=TUM2.UserID where tum1.UserID in ('54545414') 
 SELECT * from TABLE WHERE 1 = CASE when TABLE.col = 100 then 1 when TABLE.col = 200 then 2 else 3 END and TABLE.col2 = 'myname'; 

以这种方式使用。