2008-10-15 20 views
127

मैंने चारों ओर खोज करने की कोशिश की लेकिन मुझे कुछ भी नहीं मिला जो मेरी मदद करेगा।एसक्यूएल स्विच/केस जहां क्लॉज

मैं एसक्यूएल में यह करने के लिए कोशिश कर रहा हूँ:

declare @locationType varchar(50); 
declare @locationID int; 

SELECT column1, column2 
FROM viewWhatever 
WHERE 
CASE @locationType 
    WHEN 'location' THEN account_location = @locationID 
    WHEN 'area' THEN xxx_location_area = @locationID 
    WHEN 'division' THEN xxx_location_division = @locationID 

मैं जानता हूँ कि मैं '= @locationID' हर एक के अंत में डाल करने के लिए नहीं होना चाहिए कि लेकिन मैं वाक्य रचना नहीं मिल सकता है सही होने के करीब भी। एसक्यूएल पहली 'लाइन' पर मेरी '=' के बारे में शिकायत करता रहता है ...

सहायता!

उत्तर

165
declare @locationType varchar(50); 
declare @locationID int; 

SELECT column1, column2 
FROM viewWhatever 
WHERE 
@locationID = 
    CASE @locationType 
     WHEN 'location' THEN account_location 
     WHEN 'area' THEN xxx_location_area 
     WHEN 'division' THEN xxx_location_division 
    END 
+1

TomH के रूप में आपके उत्तर की टिप्पणी में नोट नीचे, आप एसक्यूएल गलत तरीके से गठन मामले की विकल्प हो सकता है। मैंने SQLServer 2005 में मेरा परीक्षण किया और यह ठीक काम किया। –

+0

@ आवश्यक क्यों हैं? वो क्या करते हैं? – JedatKinports

6

मैं कहता हूँ कि हम इस एक त्रुटिपूर्ण तालिका संरचना का सूचक है। शायद अलग-अलग स्थान प्रकारों को अलग-अलग तालिकाओं में अलग किया जाना चाहिए, जिससे आप अधिक समृद्ध पूछताछ कर सकते हैं और आस-पास के अधूरे स्तंभों से बचने में भी मदद कर सकते हैं।

आप संरचना को बदल कर पा रहे हैं, की तरह कुछ नीचे काम कर सकते हैं:

SELECT 
    * 
FROM 
    Test 
WHERE 
    Account_Location = (
     CASE LocationType 
      WHEN 'location' THEN @locationID 
      ELSE Account_Location 
     END 
    ) 
    AND 
    Account_Location_Area = (
     CASE LocationType 
      WHEN 'area' THEN @locationID 
      ELSE Account_Location_Area 
     END 
    ) 

और बहुत आगे है ... हम मक्खी पर क्वेरी की संरचना को बदल नहीं सकते, लेकिन हम भविष्यवाणियों को खुद को बराबर बनाकर इसे ओवरराइड कर सकते हैं।

संपादित करें: उपरोक्त सुझाव निश्चित रूप से बहुत बेहतर हैं, बस मेरी अनदेखी करें।

+0

मुझे नहीं लगता कि यह एक दोषपूर्ण तालिका संरचना है।तालिका इस तरह से स्थापित की गई थी ताकि यह माता-पिता/बाल संबंधों की अनंत राशि के आत्म संदर्भ हो। मेरा विश्वास करो, यह उद्देश्य पर था। मुझे नहीं लगता कि मैं सिर्फ एक स्विच स्टेटमेंट का उपयोग करने के लिए अपनी टेबल संरचना को बदलना चाहता हूं। इसके nto कि महत्वपूर्ण – Miles

4

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

आप

WHERE account_location = CASE @locationType 
           WHEN 'business' THEN 45 
           WHEN 'area' THEN 52 
         END 
तो अपने विशेष मामले में

के रूप में एक कहां खंड जब आप विधेय में कहां मापदंड जाँच कर रहे हैं, इस तरह के प्रयोग कर सकते हैं, तो आप एक संग्रहीत प्रक्रिया में क्वेरी डाल की जरूरत करने जा रहे हैं या तीन अलग प्रश्न बनाएँ।

28

यहां आप जाते हैं।

SELECT 
    column1, 
    column2 
FROM 
    viewWhatever 
WHERE 
CASE 
    WHEN @locationType = 'location' AND account_location = @locationID THEN 1 
    WHEN @locationType = 'area' AND xxx_location_area = @locationID THEN 1 
    WHEN @locationType = 'division' AND xxx_location_division = @locationID THEN 1 
    ELSE 0 
END = 1 
+5

ठीक है, मैं लिखा है कि रूप स्तम्भ 1, कॉलम 2 चयन से viewWhatever कहां (@locationType = 'स्थान' और account_location = @locationID) या (@locationType = 'क्षेत्र' और xxx_location_area = @locationID) या (@locationType = 'division' और xxx_location_division = @locationID) –

+2

यह उदाहरण की एक बड़ी शांति है, क्वेरी निष्पादन योजना के बारे में सर्वोत्तम उत्तर के साथ कैसे (व्यक्तिगत रूप से मैं इस विधि कोड को स्पष्ट और साफ़ करता हूं) – PEO

+1

वास्तव में बहुत अच्छा है यदि आप अलग-अलग प्रकार के खंड का उपयोग करना चाहते हैं, जैसे कि दूसरे खंड और द्वितीय पर nvarchar पर int। बॉब प्रॉस्ट समाधान के साथ काम नहीं करता है। धन्यवाद – Julian50

62
एक मामले बयान के बिना

...

SELECT column1, column2 
FROM viewWhatever 
WHERE 
    (@locationType = 'location' AND account_location = @locationID) 
    OR 
    (@locationType = 'area' AND xxx_location_area = @locationID) 
    OR 
    (@locationType = 'division' AND xxx_location_division = @locationID) 
+1

यह थोड़ा अलग परिणाम देगा क्योंकि केस स्टेटमेंट किसी शर्त के बाद निकलता है - लेकिन OR वाक्यविन्यास सभी संभावनाओं का मूल्यांकन करेगा – tember

+0

@tember यहां तक ​​कि यदि एसक्यूएल एक प्रक्रियात्मक भाषा थी, यदि पहला या सत्य है तो शेष अभिव्यक्ति का मूल्यांकन नहीं किया जाता है। चूंकि एसक्यूएल एक घोषणात्मक भाषा है, आप कैसे जानते हैं कि डीबीएम सभी ओआरएस का मूल्यांकन करेगा? ईमानदार सवाल, मुझे समझ में नहीं आता है। –

+0

एसक्यूएल में शेष अभिव्यक्ति का मूल्यांकन या वाक्यविन्यास में किया जाता है। इस प्रयास करें (यह मेरे @ प्रतीक शामिल नहीं जाने देंगे - आप इसे सही करने के लिए आप इसे परीक्षण करना चाहते हैं, तो होगा): घोषित वर varchar (5) सेट var = '0' का चयन 2/var जहां var <> 0 या ISNUMERIC (var) = 1 । मैं शर्त से बाहर निकलना चाहता हूं क्योंकि var 0 के बराबर है, लेकिन यह जांचने के लिए आगे बढ़ता है कि यह संख्यात्मक है, जो यह है, और इसलिए कथन एक त्रुटि देता है। – tember

3

इस क्वेरी से प्रयास करें। ऊपर पोस्ट करने के लिए उत्तर:

select @msgID, account_id 
    from viewMailAccountsHeirachy 
    where 
    CASE @smartLocationType 
     WHEN 'store' THEN account_location 
     WHEN 'area' THEN xxx_location_area 
     WHEN 'division' THEN xxx_location_division 
     WHEN 'company' THEN xxx_location_company 
    END = @smartLocation 
+1

जो भी इसे भविष्य में पढ़ता है: यह उपरोक्त @ बॉब-प्रोस्ट से स्वीकृत उत्तर जैसा ही है: http://stackoverflow.com/a/206500/264786 –

2

इस प्रयास करें:

WHERE (
    @smartLocationType IS NULL 
    OR account_location = (
     CASE 
      WHEN @smartLocationType IS NOT NULL 
       THEN @smartLocationType 
      ELSE account_location 
     END 
    ) 
) 
+0

डाउनवॉटेड क्योंकि मुझे समझ में नहीं आता कि यह कैसे चुन सकता है दिए गए तार (यानी 'स्थान', 'क्षेत्र', 'विभाजन') –

-2

इस क्वेरी का प्रयास करें। इसके बहुत आसान समझने के लिए:

CREATE TABLE PersonsDetail(FirstName nvarchar(20), LastName nvarchar(20), GenderID int); 
GO 

INSERT INTO PersonsDetail VALUES(N'Gourav', N'Bhatia', 2), 
       (N'Ramesh', N'Kumar', 1), 
       (N'Ram', N'Lal', 2), 
       (N'Sunil', N'Kumar', 3), 
       (N'Sunny', N'Sehgal', 1), 
       (N'Malkeet', N'Shaoul', 3), 
       (N'Jassy', N'Sohal', 2); 
GO 

SELECT FirstName, LastName, Gender = 
    CASE GenderID 
    WHEN 1 THEN 'Male' 
    WHEN 2 THEN 'Female' 
    ELSE 'Unknown' 
    END 
FROM PersonsDetail 
+0

जो कोई भी इस उत्तर को पढ़ता है: यह उपरोक्त @ बॉब-प्रोस्ट से स्वीकृत उत्तर जैसा ही है: http://stackoverflow.com/a/206500/264786 इस कारण से डाउनवॉटेड। –

-1
Case Statement in SQL Server Example 

Syntax 

CASE [ expression ] 

    WHEN condition_1 THEN result_1 
    WHEN condition_2 THEN result_2 
    ... 
    WHEN condition_n THEN result_n 

    ELSE result 

END 

Example 

SELECT contact_id, 
CASE website_id 
    WHEN 1 THEN 'TechOnTheNet.com' 
    WHEN 2 THEN 'CheckYourMath.com' 
    ELSE 'BigActivities.com' 
END 
FROM contacts; 

OR 

SELECT contact_id, 
CASE 
    WHEN website_id = 1 THEN 'TechOnTheNet.com' 
    WHEN website_id = 2 THEN 'CheckYourMath.com' 
    ELSE 'BigActivities.com' 
END 
FROM contacts; 
+2

डाउनवॉटेड क्योंकि यह उत्तरकर्ता प्रश्न से संबंधित नहीं है।सवाल यह था कि WHERE क्लॉज पर CASE का उपयोग कैसे करें, किसी चयनित कॉलम पर CASE का उपयोग कैसे करें। –

4

OR ऑपरेटर जब में जहां हालत

ALTER PROCEDURE [dbo].[RPT_340bClinicDrugInventorySummary] 
    -- Add the parameters for the stored procedure here 
    @ClinicId BIGINT = 0, 
    @selecttype int, 
    @selectedValue varchar (50) 
AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 
SELECT 
    drugstock_drugname.n_cur_bal,drugname.cdrugname,clinic.cclinicname 

FROM drugstock_drugname 
INNER JOIN drugname ON drugstock_drugname.drugnameid_FK = drugname.drugnameid_PK 
INNER JOIN drugstock_drugndc ON drugname.drugnameid_PK = drugstock_drugndc.drugnameid_FK 
INNER JOIN drugndc ON drugstock_drugndc.drugndcid_FK = drugndc.drugid_PK 
LEFT JOIN clinic ON drugstock_drugname.clinicid_FK = clinic.clinicid_PK 

WHERE (@ClinicId = 0 AND 1 = 1) 
    OR (@ClinicId != 0 AND drugstock_drugname.clinicid_FK = @ClinicId) 

    -- Alternative Case When You can use OR 
    AND ((@selecttype = 1 AND 1 = 1) 
    OR (@selecttype = 2 AND drugname.drugnameid_PK = @selectedValue) 
    OR (@selecttype = 3 AND drugndc.drugid_PK = @selectedValue) 
    OR (@selecttype = 4 AND drugname.cdrugclass = 'C2') 
    OR (@selecttype = 5 AND LEFT(drugname.cdrugclass, 1) = 'C')) 

ORDER BY clinic.cclinicname, drugname.cdrugname 
END 
संबंधित मुद्दे