sql - मैं एक आईएफ कैसे कर सकता हूं...फिर एक एसक्यूएल चयन में?




sql-server tsql if-statement case (20)

मैं एक IF...THEN कैसे कर सकता हूं IF...THEN एक SQL SELECT कथन में?

उदाहरण के लिए:

SELECT IF(Obsolete = 'N' OR InStock = 'Y' ? 1 : 0) AS Saleable, * FROM Product

Answers

शुद्ध बिट तर्क का प्रयोग करें:

DECLARE @Product TABLE (
    id INT PRIMARY KEY IDENTITY NOT NULL
   ,Obsolote CHAR(1)
   ,Instock CHAR(1)
)

INSERT INTO @Product ([Obsolote], [Instock])
    VALUES ('N', 'N'), ('N', 'Y'), ('Y', 'Y'), ('Y', 'N')

;
WITH cte
AS
(
    SELECT
        'CheckIfInstock' = CAST(ISNULL(NULLIF(ISNULL(NULLIF(p.[Instock], 'Y'), 1), 'N'), 0) AS BIT)
       ,'CheckIfObsolote' = CAST(ISNULL(NULLIF(ISNULL(NULLIF(p.[Obsolote], 'N'), 0), 'Y'), 1) AS BIT)
       ,*
    FROM
        @Product AS p
)
SELECT
    'Salable' = c.[CheckIfInstock] & ~c.[CheckIfObsolote]
   ,*
FROM
    [cte] c

कामकाजी डेमो देखें : अगर एमएसएसक्यूएल में मामले के बिना

प्रारंभ के लिए, आपको चयनित स्थितियों के लिए true और false के मूल्य को काम करने की आवश्यकता है। यहां दो NULLIF :

for true: ISNULL(NULLIF(p.[Instock], 'Y'), 1)
for false: ISNULL(NULLIF(p.[Instock], 'N'), 0)

एक साथ संयुक्त 1 या 0 देता है। अगला बिटवाई ऑपरेटरों का उपयोग करें।

यह सबसे WYSIWYG विधि है।


उदाहरण। कुछ इस तरह।

SELECT Salable =
        CASE Obsolete
        WHEN 'N' THEN 1
        ELSE 0
    END

 SELECT
   CASE 
      WHEN OBSOLETE = 'N' or InStock = 'Y' THEN 'TRUE' 
      ELSE 'FALSE' 
   END AS Salable,
   * 
FROM PRODUCT

  SELECT IIF(Obsolete = 'N' OR InStock = 'Y',1,0) AS Saleable, * FROM Product

उन लोगों के लिए जो SQL Server 2012 का उपयोग करते हैं, आईआईएफ एक ऐसी सुविधा है जिसे केस स्टेटमेंट के विकल्प के रूप में जोड़ा गया है और काम करता है।

SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM   Product 

case statement some what similar to if in SQL server

SELECT CASE 
            WHEN Obsolete = 'N' or InStock = 'Y' 
               THEN 1 
               ELSE 0 
       END as Saleable, * 
FROM Product

यदि आप पहली बार तालिका में परिणामों को सम्मिलित कर रहे हैं, तो एक तालिका से दूसरे में परिणामों को स्थानांतरित करने के बजाय, यह ओरेकल 11.2 जी में काम करता है:

INSERT INTO customers (last_name, first_name, city)
    SELECT 'Doe', 'John', 'Chicago' FROM dual
    WHERE NOT EXISTS 
        (SELECT '1' from customers 
            where last_name = 'Doe' 
            and first_name = 'John'
            and city = 'Chicago');

SELECT  
(CASE 
     WHEN (Obsolete = 'N' OR InStock = 'Y') THEN 'YES'
                                            ELSE 'NO' 
 END) as Salable
, * 
FROM Product

एक नई सुविधा, IIF (जिसे हम आसानी से उपयोग कर सकते हैं), SQL सर्वर 2012 में जोड़ा गया था:

SELECT IIF ( (Obsolete = 'N' OR InStock = 'Y'), 1, 0) AS Saleable, * FROM Product


इस link , हम T-SQL में IF THEN ELSE ईएलएसई को समझ सकते हैं:

IF EXISTS(SELECT *
          FROM   Northwind.dbo.Customers
          WHERE  CustomerId = 'ALFKI')
  PRINT 'Need to update Customer Record ALFKI'
ELSE
  PRINT 'Need to add Customer Record ALFKI'

IF EXISTS(SELECT *
          FROM   Northwind.dbo.Customers
          WHERE  CustomerId = 'LARSE')
  PRINT 'Need to update Customer Record LARSE'
ELSE
  PRINT 'Need to add Customer Record LARSE' 

क्या यह टी-एसक्यूएल के लिए पर्याप्त नहीं है?


CASE कथन SQL में IF के सबसे नज़दीक है और SQL सर्वर के सभी संस्करणों पर समर्थित है

SELECT CAST(
             CASE 
                  WHEN Obsolete = 'N' or InStock = 'Y' 
                     THEN 1 
                  ELSE 0 
             END AS bit) as Saleable, * 
FROM Product

यदि आप एक बूलियन मान के रूप में परिणाम चाहते हैं, तो आपको केवल CAST करने की आवश्यकता है, यदि आप किसी int खुश हैं, तो यह काम करता है:

SELECT CASE 
            WHEN Obsolete = 'N' or InStock = 'Y' 
               THEN 1 
               ELSE 0 
       END as Saleable, * 
FROM Product

CASE स्टेटमेंट अन्य CASE स्टेटमेंट्स में एम्बेड किए जा सकते हैं और यहां तक ​​कि समेकित भी शामिल हैं।

एसक्यूएल सर्वर डेनाली (एसक्यूएल सर्वर 2012) IIF स्टेटमेंट जोड़ता है जो access में भी उपलब्ध है: ( मार्टिन स्मिथ द्वारा इंगित)

SELECT IIF(Obsolete = 'N' or InStock = 'Y', 1, 0) as Saleable, * FROM Product

SELECT 1 AS Saleable, *
  FROM @Product
 WHERE ( Obsolete = 'N' OR InStock = 'Y' )
UNION
SELECT 0 AS Saleable, *
  FROM @Product
 WHERE NOT ( Obsolete = 'N' OR InStock = 'Y' )

एक केस स्टेटमेंट का प्रयोग करें:

SELECT CASE
       WHEN (Obsolete = 'N' OR InStock = 'Y')
       THEN 'Y'
       ELSE 'N'
END as Available

etc...

यह एक उत्तर नहीं है, जहां मैं काम करता हूं वहां उपयोग में एक केस स्टेटमेंट का एक उदाहरण है। इसमें घोंसला वाला केस स्टेटमेंट है। अब आप जानते हैं कि मेरी आंखें क्यों पार हो गई हैं।

 CASE orweb2.dbo.Inventory.RegulatingAgencyName
    WHEN 'Region 1'
        THEN orweb2.dbo.CountyStateAgContactInfo.ContactState
    WHEN 'Region 2'
        THEN orweb2.dbo.CountyStateAgContactInfo.ContactState
    WHEN 'Region 3'
        THEN orweb2.dbo.CountyStateAgContactInfo.ContactState
    WHEN 'DEPT OF AGRICULTURE'
        THEN orweb2.dbo.CountyStateAgContactInfo.ContactAg
    ELSE (
            CASE orweb2.dbo.CountyStateAgContactInfo.IsContract
                WHEN 1
                    THEN orweb2.dbo.CountyStateAgContactInfo.ContactCounty
                ELSE orweb2.dbo.CountyStateAgContactInfo.ContactState
                END
            )
    END AS [County Contact Name]

SELECT CASE WHEN profile.nrefillno = 0 THEN 'N' ELSE 'R'END as newref
From profile

SQL सर्वर 2012 से आप इसके लिए IIF फ़ंक्शन का उपयोग कर सकते हैं।

SELECT IIF(Obsolete = 'N' OR InStock = 'Y', 1, 0) AS Salable, *
FROM   Product 

यह प्रभावी रूप से सिर्फ एक शॉर्टेंड (हालांकि मानक एसक्यूएल नहीं है) CASE लिखने का तरीका है।

विस्तारित CASE संस्करण के साथ तुलना करते समय मैं एकजुटता पसंद करता हूं।

IIF() और IIF() दोनों SQL स्टेटमेंट के भीतर अभिव्यक्ति के रूप में हल होते हैं और केवल अच्छी तरह से परिभाषित स्थानों में उपयोग किए जा सकते हैं।

CASE अभिव्यक्ति का उपयोग ट्रांजैक्ट-एसक्यूएल कथन, कथन ब्लॉक, उपयोगकर्ता परिभाषित कार्यों और संग्रहीत प्रक्रियाओं के निष्पादन के प्रवाह को नियंत्रित करने के लिए नहीं किया जा सकता है।

यदि आपकी ज़रूरतें इन सीमाओं से संतुष्ट नहीं हो सकती हैं (उदाहरण के लिए अलग-अलग आकार के परिणाम सेट करने की आवश्यकता कुछ शर्त पर निर्भर होती है) तो SQL सर्वर में एक प्रक्रियात्मक IF कीवर्ड भी होता है।

IF @IncludeExtendedInformation = 1 
  BEGIN 
      SELECT A,B,C,X,Y,Z 
      FROM   T 
  END 
ELSE 
  BEGIN 
      SELECT A,B,C 
      FROM   T 
  END 

हालांकि इस दृष्टिकोण के साथ पैरामीटर स्नीफिंग मुद्दों से बचने के लिए कभी-कभी देखभाल की जानी चाहिए।


माइक्रोसॉफ्ट एसक्यूएल सर्वर (टी-एसक्यूएल)

एक चुनिंदा उपयोग में:

select case when Obsolete = 'N' or InStock = 'Y' then 'YES' else 'NO' end

जहां एक खंड में, उपयोग करें:

where 1 = case when Obsolete = 'N' or InStock = 'Y' then 1 else 0 end

SELECT CASE WHEN Obsolete = 'N' or InStock = 'Y' THEN 1 ELSE 0 
             END AS Saleable, * 
FROM Product

मैं एहसान संग्रहित प्रक्रियाओं ( MySQL 5.0 के बाद से संग्रहित प्रक्रियाओं का समर्थन किया गया है ) को देखने के एक सुरक्षा बिंदु से - फायदे हैं -

  1. अधिकांश डेटाबेस ( MySQL समेत ) संग्रहीत प्रक्रियाओं को निष्पादित करने के लिए उपयोगकर्ता पहुंच को प्रतिबंधित करने में सक्षम बनाता है। बढ़िया सुरक्षा पहुंच नियंत्रण विशेषाधिकारों के हमलों की वृद्धि को रोकने के लिए उपयोगी है। यह समझौता किए गए अनुप्रयोगों को डेटाबेस के विरुद्ध सीधे SQL चलाने में सक्षम होने से रोकता है।
  2. वे अनुप्रयोग से कच्चे एसक्यूएल क्वेरी को सारणी देते हैं ताकि डेटाबेस संरचना की कम जानकारी एप्लिकेशन के लिए उपलब्ध हो। यह लोगों के डेटाबेस की अंतर्निहित संरचना को समझने और उपयुक्त हमलों को डिजाइन करने के लिए कठिन बनाता है।
  3. वे केवल पैरामीटर स्वीकार करते हैं, इसलिए पैरामीटरयुक्त प्रश्नों के फायदे हैं। बेशक - आईएमओ आपको अभी भी अपने इनपुट को स्वच्छ करने की आवश्यकता है - खासकर अगर आप संग्रहीत प्रक्रिया के अंदर गतिशील एसक्यूएल का उपयोग कर रहे हैं।

नुकसान हैं -

  1. वे (संग्रहीत प्रक्रियाओं) को बनाए रखने के लिए कठिन हैं और बहुत तेज़ी से गुणा करते हैं। इससे उन्हें एक मुद्दा मिल जाता है।
  2. वे गतिशील प्रश्नों के लिए बहुत उपयुक्त नहीं हैं - यदि वे पैरामीटर के रूप में गतिशील कोड स्वीकार करने के लिए बनाए गए हैं तो बहुत से फायदे अस्वीकार कर दिए जाते हैं।




sql sql-server tsql if-statement case