SQL: यदि क्लॉज़ WHERE क्लॉज़ में है


203

क्या MS SQL में WHERE क्लॉज के भीतर एक IF क्लॉज का उपयोग करना संभव है ?

उदाहरण:

WHERE
    IF IsNumeric(@OrderNumber) = 1
        OrderNumber = @OrderNumber
    ELSE
        OrderNumber LIKE '%' + @OrderNumber + '%'

जवाबों:


212

एक केस स्टेटमेंट का उपयोग करें
: पिछला सिंटैक्स (जैसा कि कुछ लोगों द्वारा बताया गया है) काम नहीं करता है। आप CASE का उपयोग इस प्रकार कर सकते हैं:

WHERE OrderNumber LIKE
  CASE WHEN IsNumeric(@OrderNumber) = 1 THEN 
    @OrderNumber 
  ELSE
    '%' + @OrderNumber
  END

या आप @ NJ रीड पॉइंट्स जैसे IF स्टेटमेंट का उपयोग कर सकते हैं ।


[लेखक द्वारा अद्यतन के बाद नोट]: यह काम करना चाहिए, लेकिन आपको यह सुनिश्चित करने के लिए TRIM () दोनों तरफ होना चाहिए कि एक मैच मिला है। मुझे लगता है कि वहाँ अभी भी किनारे के मामले हैं जो मैच करने में विफल रहते हैं।
यूरो मिकेली

1
का उपयोग करना CASEज्यादातर मामलों में उचित समाधान है। मेरे मामले में, मैं तुलना ऑपरेटर को बदलना चाहता था और इसलिए मैंने अगले दृष्टिकोण का उपयोग किया।
बिड़ला

142

आपको बिना किसी IF या CASE के ऐसा करने में सक्षम होना चाहिए

 WHERE 
   (IsNumeric(@OrderNumber) AND
      (CAST OrderNumber AS VARCHAR) = (CAST @OrderNumber AS VARCHAR)
 OR
   (NOT IsNumeric(@OrderNumber) AND
       OrderNumber LIKE ('%' + @OrderNumber))

SQL के स्वाद पर निर्भर करता है कि आपको आदेश संख्या पर INT या VARCHAR को जातियों को मोड़ना पड़ सकता है, जो इस बात पर निर्भर करता है कि निहित जाति समर्थित हैं।

यह WHERE क्लॉज में एक बहुत ही सामान्य तकनीक है। यदि आप WHERE क्लॉज में कुछ "IF" लॉजिक लागू करना चाहते हैं, तो आपको एक बूलियन और उस सेक्शन के साथ अतिरिक्त स्थिति जोड़ना होगा, जहाँ इसे लागू करने की आवश्यकता है।


2
मुझे लगता है कि आप CASE समाधान पर हिट प्रदर्शन का एक सा ले लेंगे, हालांकि, चूंकि उन सभी परिस्थितियों का मूल्यांकन किया जाता है, नहीं?
केविन फेयरचाइल्ड

मैं हमेशा यह भूल जाता हूं कि एसक्यूएल में बूलियन लॉजिक के साथ सशर्त बयानों को प्रतिस्थापित किया जा सकता है। अनुस्मारक के लिए धन्यवाद, यह एक बहुत ही उपयोगी तकनीक है!
कोडेक्सआर्कनम

1
यह समाधान वास्तव में सबसे अच्छा है कि SQL सर्वर बूलियन लॉजिक को कैसे संसाधित करता है। उन बयानों में जहां क्लॉस बूलियन मामलों की तुलना में कम कुशल हैं यदि पहली जांच विफल हो जाती है, तो एसक्यूएल लाइन को संसाधित करना बंद कर देगा और जारी रहेगा। यह आपको प्रसंस्करण समय बचाता है। इसके अलावा, हमेशा अपने बूलियन चेक के दूसरी तरफ अधिक महंगा स्टेटमेंट डालें।
स्टीव

एक बहुत ही सुंदर समाधान के लिए धन्यवाद। आपके द्वारा उपयोग की गई विधि पर एक ट्यूटोरियल मिला जो लोगों की मदद कर सकता है। weblogs.sqlteam.com/jeffs/archive/2003/11/14/513.aspx
अमीर

1
@ आपके द्वारा प्रदान किया गया लिंक एक रजिस्टर-टू-रीड है, क्या कोई सार्वजनिक रूप से उपलब्ध डॉक्यूमेंटेशन है जो बताता है कि आप क्या कह रहे हैं?
स्टीव

29

आपको एक IF स्टेटमेंट की आवश्यकता नहीं है।

WHERE
    (IsNumeric(@OrderNumber) = 1 AND OrderNumber = @OrderNumber)
OR (IsNumeric(@OrderNumber) = 0 AND OrderNumber LIKE '%' + @OrderNumber + '%')

2
मुझे वास्तव में यह दृष्टिकोण पसंद है। अल्टरनेटिव का उपयोग करता है: केवल फ़िल्टर अगर AdmUseId का कोई मान है: where (@AdmUserId is null or CurrentOrder.CustomerAdmUserId = @AdmUserId) या केवल फ़िल्टर करें अगर शामिल किया गया = 0: where (@IncludeDeleted = 1 or ItemObject.DeletedFlag = 0)
Kasper Halvas Jensen

WHERE क्लॉज में IN फ़िल्टर का उपयोग करते समय यह अच्छी तरह से काम करता है। यह CASE के साथ ऐसा करने में गड़बड़ करता है क्योंकि आपको COALESCE का उपयोग करना है और इसे पढ़ना कठिन है, जबकि यह पढ़ने में सीधा तर्क है। TSQL मामले में कहां या फिल्टर में नहीं के लिए खंड
pholcroft

14

SQL में ऐसा करने का अच्छा तरीका नहीं है। कुछ दृष्टिकोण जो मैंने देखे हैं:

1) बूलियन ऑपरेटरों के साथ संयुक्त मामले का उपयोग करें:

WHERE
    OrderNumber = CASE 
        WHEN (IsNumeric(@OrderNumber) = 1)
        THEN CONVERT(INT, @OrderNumber)
        ELSE -9999 -- Some numeric value that just cannot exist in the column
    END
    OR 
    FirstName LIKE CASE
        WHEN (IsNumeric(@OrderNumber) = 0)
        THEN '%' + @OrderNumber
        ELSE ''
    END

2) चयन के बाहर IF का उपयोग करें

IF (IsNumeric(@OrderNumber)) = 1
BEGIN
    SELECT * FROM Table
    WHERE @OrderNumber = OrderNumber
END ELSE BEGIN
    SELECT * FROM Table
    WHERE OrderNumber LIKE '%' + @OrderNumber
END

3) एक लंबी स्ट्रिंग का उपयोग करके, अपने SQL स्टेटमेंट को सशर्त रूप से लिखें, और फिर EXEC का उपयोग करें

3 डी दृष्टिकोण घृणित है, लेकिन यह लगभग केवल यही सोचता है कि अगर आपके पास इस तरह की कई परिवर्तनशील स्थितियां हैं तो काम करता है।


चौथा तरीका यह है कि अपने सभी सशर्तों IF...ELSE...को बूलियन ANDके ORरूप में @ nrr101 उत्तर में ऊपर में परिवर्तित करें। ^ के नीचे यह दृष्टिकोण यह है कि अगर आप बहुत से हैं, तो यह दिमागी रूप से मुश्किल हो सकता है IF, या यदि आपके पास कई हैं जो घोंसले में हैं
डॉन Cheadle



3

मुझे लगता है कि जहां ... जैसे / = ... मामला ... तब ... बूलियंस के साथ काम कर सकता है। मैं टी-एसक्यूएल का उपयोग कर रहा हूं।

परिदृश्य: मान लीजिए कि आप बूल झूठ बोलना चाहते हैं, तो पर्सन -30 के शौक को प्राप्त करना चाहते हैं, और बस्ट के सच होने पर पर्सन -42 का शौक। (कुछ के अनुसार, शौक-लुकअप में 90% से अधिक व्यावसायिक संगणना चक्र शामिल होते हैं, इसलिए करीब से भुगतान करें।)

CREATE PROCEDURE sp_Case
@bool   bit
AS
SELECT Person.Hobbies
FROM Person
WHERE Person.ID = 
    case @bool 
        when 0 
            then 30
        when 1
            then 42
    end;

2
कहां (IsNumeric (@OrderNumber) <> 1 या ऑर्डरनंबर = @OrderNumber) 
             और (IsNumber (@OrderNumber) = 1 या ऑर्डरनंबर '%' पसंद करें 
                                              + @ ऑडरनंबर + '%')

IF P THEN Q ELSE R <=> ( ( NOT P ) OR Q ) AND ( P OR R )
कंजंक्टिव

1

मामला वक्तव्य से बेहतर विकल्प है यदि हमेशा।

  WHERE  vfl.CreatedDate >= CASE WHEN @FromDate IS NULL THEN vfl.CreatedDate ELSE  @FromDate END
    AND vfl.CreatedDate<=CASE WHEN @ToDate IS NULL THEN vfl.CreatedDate ELSE @ToDate END 

1
    WHERE OrderNumber LIKE CASE WHEN IsNumeric(@OrderNumber) = 1 THEN @OrderNumber ELSE  '%' + @OrderNumber END

लाइन केस में कंडीशन ठीक से काम करेगी।


0

निम्न उदाहरण बूलियन अभिव्यक्ति के हिस्से के रूप में एक क्वेरी को निष्पादित करता है और फिर बूलियन अभिव्यक्ति के परिणाम के आधार पर थोड़ा अलग स्टेटमेंट ब्लॉक निष्पादित करता है। प्रत्येक स्टेटमेंट ब्लॉक BEGIN से शुरू होता है और END के साथ पूरा होता है।

USE AdventureWorks2012;
GO
DECLARE @AvgWeight decimal(8,2), @BikeCount int
IF 
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
BEGIN
   SET @BikeCount = 
        (SELECT COUNT(*) 
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%');
   SET @AvgWeight = 
        (SELECT AVG(Weight) 
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%');
   PRINT 'There are ' + CAST(@BikeCount AS varchar(3)) + ' Touring-3000 bikes.'
   PRINT 'The average weight of the top 5 Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.';
END
ELSE 
BEGIN
SET @AvgWeight = 
        (SELECT AVG(Weight)
         FROM Production.Product 
         WHERE Name LIKE 'Touring-3000%' );
   PRINT 'Average weight of the Touring-3000 bikes is ' + CAST(@AvgWeight AS varchar(8)) + '.' ;
END ;
GO

नेस्टेड IF का उपयोग करना ... ELSE स्टेटमेंट निम्न उदाहरण दिखाता है कि कैसे एक IF ... ELSE स्टेटमेंट को दूसरे के अंदर नेस्ट किया जा सकता है। प्रत्येक स्टेटमेंट को जांचने के लिए @Number वैरिएबल को 5, 50 और 500 पर सेट करें।

DECLARE @Number int
SET @Number = 50
IF @Number > 100
   PRINT 'The number is large.'
ELSE 
   BEGIN
      IF @Number < 10
      PRINT 'The number is small'
   ELSE
      PRINT 'The number is medium'
   END ;
GO

2
यह प्रासंगिक नहीं लगता है। यह WHERE क्लॉज में IF (या कोई भी सशर्त कोड) का उपयोग नहीं करता है।
विंस बॉड्रेन

0

Sql सर्वर में मुझे एक ही समस्या थी कि मैं एक और स्टेटमेंट का उपयोग करना चाहता था यदि पैरामीटर गलत है और सही पर मुझे दोनों मानों को सही और गलत दिखाना है तो मैंने इसे इस तरह से उपयोग किया

(T.IsPublic = @ShowPublic or  @ShowPublic = 1)

-1
If @LstTransDt is Null
                begin
                    Set @OpenQty=0
                end
            else
                begin
                   Select   @OpenQty=IsNull(Sum(ClosingQty),0)  
                   From  ProductAndDepotWiseMonitoring  
                   Where   Pcd=@PCd And PtpCd=@PTpCd And TransDt=@LstTransDt      
                end 

देखें कि क्या यह मदद करता है।


-6
USE AdventureWorks2012;
GO
IF 
(SELECT COUNT(*) FROM Production.Product WHERE Name LIKE 'Touring-3000%' ) > 5
PRINT 'There are more than 5 Touring-3000 bicycles.'
ELSE PRINT 'There are 5 or less Touring-3000 bicycles.' ;
GO

यह प्रासंगिक नहीं लगता है। यह WHERE क्लॉज में IF (या कोई भी सशर्त कोड) का उपयोग नहीं करता है।
विंस बॉड्रेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.