SQL सर्वर 2008 में "WHERE" क्लॉज़ के भीतर "CASE" कथन


107

मैं एक क्वेरी के साथ काम कर रहा हूं जिसमें "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

2
केस एक्सप्रेशन , स्टेटमेंट नहीं ... (केस एक्सप्रेशन एक मान देता है। केस स्टेटमेंट को कोड के सशर्त निष्पादन के लिए संग्रहीत प्रक्रियाओं में उपयोग किया जाता है।)
jarlh

जवाबों:


205

सबसे पहले, 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 

इस तरह के संयुक्त या बयानों का उपयोग करने से आपकी किस्मत अच्छी हो सकती है:

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

हालाँकि, किसी भी तरह से मुझे यकीन नहीं है कि आपको कितनी बढ़िया योजना मिलेगी। एक WHEREखंड में इस तरह के शेननिगैन अक्सर क्वेरी ऑप्टिमाइज़र को अनुक्रमित करने से रोकते हैं।


1
जब यह सह हो जाता है, तो यह चेक co.personentered = co.personentered की जरूरत नहीं है क्योंकि यह हमेशा सही रहेगा और लंबाई मान हमेशा सकारात्मक रहेगा। इसलिए, LEN ('टेस्टपेरसन')> 0 की तुलना की जाने वाली आवश्यक सीमा को कम कर देगा
सत्यजीत

कैसे जांचना co.personenteredशून्य नहीं है, विकल्प 1 और 2 में। अब 3 आरडी विकल्प पर्याप्त है। लेकिन मैं जानना चाहता हूँ कि ... !!
पुगल

मैंने अब तक की कोशिश की where case c when 1 then (DescriptionCode is null) else descriptioncode is not null end, लेकिन मैं त्रुटि को दिखाता हैIncorrect syntax near the keyword 'is'.
पुगल

15

यह समय के लिए आपकी समस्या को हल करना चाहिए, लेकिन मुझे आपको याद दिलाना चाहिए कि यह एक अच्छा तरीका नहीं है:

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 

12

निम्नलिखित प्रयास करें:

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

6

मुझे लगता है कि आपकी क्वेरी की शुरुआत इस तरह दिखनी चाहिए:

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 

परंतु

पूंछ में क्या है पूरी तरह से समझ में नहीं आता है


4

कुछ 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 

1

आप नीचे दिए गए उदाहरणों की तरह भी प्रयास कर सकते हैं। केवल आउटबाउंड शिपमेंट दिखाने के लिए

   SELECT shp_awb_no,shpr_ctry_cd, recvr_ctry_cd,
     CASE WHEN shpr_ctry_cd = record_ctry_cd 
     THEN "O" 
     ELSE "I" 
      END AS route
     FROM shipment_details
    WHERE record_ctry_cd = "JP"
      AND "O" = CASE WHEN shpr_ctry_cd = record_ctry_cd 
                THEN "O" 
                ELSE "I" 
                 END

1

इस सवाल के लिए धन्यवाद, वास्तव में मैं कुछ और खोज रहा हूं जो नीचे क्वेरी में है। यह किसी की मदद कर सकता है।

      SELECT DISTINCT CASE WHEN OPPORTUNITY='' THEN '(BLANK)' ELSE OPPORTUNITY END
  AS OPP,LEN(OPPORTUNITY) FROM [DBO].[TBL]

उपरोक्त क्वेरी ड्रॉपडाउन में भरना है जो रिक्त मान "(रिक्त)" के रूप में दिखाता है। इसके अलावा, यदि हम इस मान को sql में पास करते हैं जहाँ खंड को अन्य मानों के साथ रिक्त मान प्राप्त करने के लिए है जो मुझे नहीं पता कि इसे कैसे संभालना है। और अंत में नीचे समाधान के साथ आया यह किसी को मदद कर सकता है।

यह रहा ,

 DECLARE @OPP TABLE (OPP VARCHAR(100))
  INSERT INTO @OPP VALUES('(BLANK)'),('UNFUNDED'),('FUNDED/NOT COMMITTED')
SELECT DISTINCT [OPPORTUNITY]
FROM [DBO].[TBL]   WHERE    (  CASE WHEN   OPPORTUNITY ='' THEN '(BLANK)' ELSE OPPORTUNITY END IN (SELECT OPP FROM @OPP))
ORDER BY 1 

0

यहाँ मेरा समाधान है

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

सादर डेवी


0

यह काम

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)

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

निम्नलिखित प्रयास करें:

... and ( 
    (LEN('TestPerson') = 0 and co.personentered  = co.personentered) or
    (LEN('TestPerson') <> 0 and co.personentered LIKE '%TestPerson') ) and ...

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

-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';

इस तरह से उपयोग करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.