2012-01-09 35 views
73

Tôi đang làm việc với truy vấn có chứa câu lệnh "CASE" trong mệnh đề "WHERE". Nhưng SQL Server 2008 đang đưa ra một số lỗi trong khi thực thi nó. Bất cứ ai có thể vui lòng giúp tôi với các truy vấn chính xác? Dưới đây là các truy vấn:câu lệnh "CASE" trong mệnh đề "WHERE" trong 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 

Trả lời

146

Trước hết, báo cáo kết quả CASE phải phần của biểu thức, không phải là biểu hiện riêng của mình.

Nói cách khác, bạn có thể có:

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

Nhưng nó sẽ không làm việc theo cách bạn đã viết chúng, thí dụ:

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

Bạn có thể có may mắn hơn sử dụng báo cáo kết hợp HOẶC như này:

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

Mặc dù, dù sao thì tôi không chắc chắn về kế hoạch truy vấn của bạn. Các loại shenanigans này trong mệnh đề WHERE thường sẽ ngăn trình tối ưu hóa truy vấn sử dụng các chỉ mục.

+1

KHI 0 THEN đồng .p ersonentered = co.personentered, Ở đây kiểm tra này co.personentered = co.personentered là không cần thiết vì nó sẽ luôn trả về giá trị true và length sẽ luôn dương. Vì vậy, làm cho LEN ('TestPerson')> 0 sẽ giảm phạm vi cần thiết để so sánh – Satyajit

5

Tôi nghĩ rằng đầu truy vấn của bạn sẽ giống như thế:

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 

NHƯNG

gì là ở đuôi là hoàn toàn không thể hiểu

12

này nên giải quyết vấn đề của bạn cho hiện tại nhưng tôi phải nhắc bạn rằng đó không phải là cách tiếp cận tốt:

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 
-1
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') 
10

Hãy thử như sau:

select * From emp_master 
where emp_last_name= 
case emp_first_name 
when 'test' then 'test' 
when 'Mr name' then 'name' 
end 
-3
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'; 

Sử dụng theo cách này.

2

WHERE phần có thể được viết như thế này:

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 
0

đây là giải pháp của tôi

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

Regads Davy

0

này hoạt động

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) 
Các vấn đề liên quan