टी-एसक्यूएल केस क्लॉज़: जब पूरा निर्दिष्ट करना है


227

मैंने इस तरह से एक टी-एसक्यूएल स्टेटमेंट लिखा (मूल एक अलग दिखता है लेकिन मैं यहां एक आसान उदाहरण देना चाहता हूं):

SELECT first_name + 
    CASE last_name WHEN null THEN 'Max' ELSE 'Peter' END AS Name
FROM dbo.person

इस कथन में कोई सिंटैक्स त्रुटियाँ नहीं हैं, लेकिन केस-क्लॉज़ हमेशा ELSE-part को चुनता है - भले ही last_name शून्य हो। लेकिन क्यों?

मैं जो करना चाहता हूं वह पहले_नाम और अंतिम_नाम को एकजुट करना है, लेकिन अगर अंतिम_नाम शून्य है तो पूरा नाम शून्य हो जाता है:

SELECT first_name +
   CASE last_name WHEN null THEN '' ELSE ' ' + last_name END AS Name 
FROM dbo.person

क्या आप जानते हैं कि समस्या कहां है?

जवाबों:


369
CASE WHEN last_name IS NULL THEN '' ELSE ' '+last_name END

4
@ लूथर का COALESCE सुझाव मेरे उत्तर से बेहतर है। यह थोड़ा कम कुशल है, लेकिन बहुत अधिक सुरुचिपूर्ण है।
मार्सेलो कैंटोस

इसे कुछ इस तरह से संभालना उपयोग की तरह हो सकता है, या कुछ इस तरह का हो सकता है: COALESCE (last_name, '') मामले का कथन, संक्षिप्त रूप में, बड़े प्रश्नों में COALESCE की तुलना में कम बनाए रखने योग्य है। अंत में, आपके पास एक ही परिणाम है। यदि आपको अनुकूलन करने की आवश्यकता है, तो निष्पादन योजनाओं की जांच करें लेकिन मैंने बहुत अंतर नहीं देखा है।
एंथनी मेसन

1
COALESCEमूल रूप से आंतरिक रूप से अनुवाद करता है CASE। CASE के साथ समस्या last_nameका मूल्यांकन दो बार किया जाता है और इससे अन्य दुष्प्रभाव हो सकते हैं - इस उत्कृष्ट लेख को देखें । जो पूछा गया था, उसे हल करने के लिए, मैं नीचे टिप्पणी के साथ ISNULL(' '+ last_name, '')उल्लेख करना चाहूंगा ।
miroxlav

41

जब भाग की तुलना == से की जाती है, लेकिन आप वास्तव में NULL से तुलना नहीं कर सकते। प्रयत्न

CASE WHEN last_name is NULL  THEN ... ELSE .. END

इसके बजाय या कोड:

COALESCE(' '+last_name,'')

('' + last_name NULL तब होता है जब last_name NULL होता है, इसलिए उस स्थिति में इसे वापस करना चाहिए ''


ठीक है जब आप भाग में == के साथ जानकारी के लिए धन्यवाद। मुझे नहीं पता था। COALESCE के साथ यह ठीक काम भी करता है। सोचा नहीं था कि ऐसा करने के लिए बहुत संभावनाएं हैं।
मेनी

15

बहुत सारे समाधान हैं, लेकिन कोई भी कवर नहीं करता है कि मूल कथन काम क्यों नहीं करता है।

CASE last_name WHEN null THEN '' ELSE ' '+last_name

जब के बाद, समानता के लिए एक जांच होती है, जो सही या गलत होनी चाहिए।

यदि तुलना का एक या दोनों भाग शून्य है, तो तुलना का परिणाम UNKNOWN होगा, जिसे केस संरचना में गलत माना जाता है। देखें: https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/

इससे बचने के लिए, कोलेसस सबसे अच्छा तरीका है।


11

अपनी क्वेरी को देखते हुए आप यह भी कर सकते हैं:

SELECT first_name + ' ' + ISNULL(last_name, '') AS Name FROM dbo.person

2
अंतिम_नाम शून्य होने पर यह एक बेमानी जगह जोड़ता है, जिसे ओपी बचने की कोशिश कर रहा था।
मार्सेलो कैंटोस

6
ISNULL(' '+ last_name, '')बेमानी जगह को रोकने के लिए बेहतर उपयोग ।
प्रूत्स्वोन्दर

मेरे पोस्ट करने के बाद हाँ का एहसास हुआ। मुझे लगा कि जब वह उस हिस्से को हल कर लेगा, जिससे वह परेशान था।
इयान जैकब्स

7

समस्या यह है कि नल को स्वयं के बराबर नहीं माना जाता है, इसलिए खंड कभी मेल नहीं खाता है।

आपको स्पष्ट रूप से नल की जांच करने की आवश्यकता है:

SELECT CASE WHEN last_name is NULL THEN first_name ELSE first_name + ' ' + last_name

5

प्रयत्न:

SELECT first_name + ISNULL(' '+last_name, '') AS Name FROM dbo.person

यह अंतिम नाम के लिए स्थान जोड़ता है, यदि यह शून्य है, तो पूरा स्थान + अंतिम नाम NULL में चला जाता है और आपको केवल पहला नाम मिलता है, अन्यथा आपको एक फ़र्स्ट + स्पेस + अंतिम नाम मिलता है।

यह तब तक काम करेगा जब तक कि अशक्त तारों के साथ संयोजन के लिए डिफ़ॉल्ट सेटिंग सेट न हो जाए:

SET CONCAT_NULL_YIELDS_NULL ON 

यह एक चिंता का विषय नहीं होना चाहिए क्योंकि OFFमोड SQl सर्वर के भविष्य के संस्करणों में दूर जा रहा है


4

मुद्दा यह है कि NULL को किसी चीज़ के बराबर भी नहीं माना जाता है, लेकिन अजीब बात यह है कि यह अपने आप के बराबर भी नहीं है।

निम्नलिखित कथनों पर विचार करें (जो SQL सर्वर T-SQL में BTW अवैध है, लेकिन My-SQL में मान्य है, हालांकि यह वही है जो ANSI शून्य के लिए परिभाषित करता है, और केस स्टेटमेंट आदि का उपयोग करके SQL सर्वर में भी सत्यापित किया जा सकता है)

SELECT NULL = NULL -- Results in NULL

SELECT NULL <> NULL -- Results in NULL

अतः प्रश्न का कोई सही / गलत उत्तर नहीं है, इसके बजाय उत्तर भी अशक्त है।

उदाहरण के लिए, इसके कई निहितार्थ हैं

  1. मामला बयान है, जो किसी भी शून्य मान हमेशा और खंड का उपयोग करेगा जब तक आप स्पष्ट का उपयोग करते हैं शून्य हालत (IS NOT हालत )WHEN NULL
  2. स्ट्रिंग संघनन, के रूप में
    SELECT a + NULL -- Results in NULL
  3. यदि आप सही परिणाम चाहते हैं, तो किसी भी शून्य मान को फ़िल्टर करने के लिए सहसंबद्ध उप-क्वेरी में सुनिश्चित करने के लिए, जहाँ या उसके खंड में नहीं है।

कोई निर्दिष्ट करके SQL सर्वर में इस व्यवहार को ओवरराइड कर सकता है SET ANSI_NULLS OFF, हालांकि यह अनुशंसित नहीं है और ऐसा नहीं किया जाना चाहिए क्योंकि यह कई मुद्दों का कारण बन सकता है, बस इसलिए कि मानक का विचलन।

(साइड नोट के रूप में, माय-एसक्यूएल में <=>शून्य तुलना के लिए एक विशेष ऑपरेटर का उपयोग करने का विकल्प है ।)

इसकी तुलना में, सामान्य प्रोग्रामिंग भाषाओं में शून्य का उपचार एक नियमित मूल्य है और यह स्वयं के बराबर है, हालांकि एनएएन मूल्य है जो स्वयं के बराबर भी नहीं है, लेकिन कम से कम यह 'झूठी' रिटर्न देता है जब इसकी तुलना में, (और जब समान प्रोग्रामिंग के लिए जाँच नहीं होती है तो विभिन्न प्रोग्रामिंग भाषाओं में अलग-अलग कार्यान्वयन होते हैं)।

ध्यान दें कि बुनियादी भाषाओं (अर्थात VB आदि) में कोई 'शून्य' कीवर्ड नहीं है और इसके बजाय कोई 'कुछ भी नहीं' कीवर्ड का उपयोग करता है, जिसका उपयोग प्रत्यक्ष तुलना में नहीं किया जा सकता है और इसके बजाय किसी को SQL में 'IS' का उपयोग करने की आवश्यकता होती है, हालाँकि यह वास्तव में खुद के बराबर है (अप्रत्यक्ष तुलना का उपयोग करते समय)।


1
"अजीब बात यह है कि यह भी खुद के बराबर नहीं है।" => यह अजीब नहीं है कि SQL में अशक्त का अर्थ 'अज्ञात' है। कुछ अज्ञात, सबसे अधिक संभावना नहीं है कि कुछ और जैसा कि अनकाउन्ट है।
जेडीसी


1

जब आप इस कोशिश में निराश हो जाते हैं:

CASE WHEN last_name IS NULL THEN '' ELSE ' '+last_name END

इसके बजाय यह प्रयास करें:

CASE LEN(ISNULL(last_Name,''))
WHEN 0 THEN '' 
ELSE ' ' + last_name
END AS newlastName

LEN(ISNULL(last_Name,''))उस कॉलम में वर्णों की संख्या को मापता है, जो शून्य हो जाएगा चाहे वह खाली हो, या NULL, इसलिए WHEN 0 THENयह सही होने पर मूल्यांकन करेगा और जैसा कि अपेक्षित था, वापस कर देगा।

मुझे उम्मीद है कि यह एक उपयोगी विकल्प है।

मैंने इस परीक्षण मामले को sql सर्वर 2008 और उससे ऊपर के लिए शामिल किया है:

DECLARE @last_Name varchar(50) = NULL

SELECT 
CASE LEN(ISNULL(@last_Name,''))
WHEN 0 THEN '' 
ELSE 'A ' + @last_name
END AS newlastName

SET @last_Name = 'LastName'

SELECT 
CASE LEN(ISNULL(@last_Name,''))
WHEN 0 THEN '' 
ELSE 'A ' + @last_name
END AS newlastName

2
क्या आप सुनिश्चित हैं कि काम करता है? जब फुल इनपुट दिया जाता है तो ज्यादातर फंक्शन NULL लौटते हैं और मेरे टेस्ट कन्फर्म करते हैं कि LEN () का भी सच है, यानी, LEN (NULL) NULL नहीं, 0.
जेसन मुस्ग्रेव

Pokechu22 सही है, और यह सही स्क्रिप्ट है: CAS LEN (ISNULL (last_Name, '')) WHEN 0 THEN '' ELSE '' + last_name END AS newlastName
Slagle

0

जेसन ने एक त्रुटि पकड़ी, इसलिए यह काम करता है ...

क्या कोई अन्य प्लेटफ़ॉर्म संस्करणों की पुष्टि कर सकता है?
एस क्यू एल सर्वर:

SELECT
CASE LEN(ISNULL(last_name,'')) 
WHEN 0 THEN '' 
ELSE ' ' + last_name
END AS newlastName

माई एसक्यूएल:

SELECT
CASE LENGTH(IFNULL(last_name,'')) 
WHEN 0 THEN '' 
ELSE ' ' + last_name
END AS newlastName

आकाशवाणी:

SELECT
CASE LENGTH(NVL(last_name,'')) 
WHEN 0 THEN '' 
ELSE ' ' + last_name
END AS newlastName

0

आप IsNull फ़ंक्शन का उपयोग कर सकते हैं

select 
    isnull(rtrim(ltrim([FirstName]))+' ','') +
    isnull(rtrim(ltrim([SecondName]))+' ','') +
    isnull(rtrim(ltrim([Surname]))+' ','') +
    isnull(rtrim(ltrim([SecondSurname])),'')
from TableDat

यदि एक कॉलम शून्य है, तो आपको एक खाली चार्ट मिलेगा

Microsoft SQL Server 2008+ के साथ संगत


0

SQL सर्वर 2012 में उपलब्ध CONCAT फ़ंक्शन का उपयोग करें।

SELECT CONCAT([FirstName], ' , ' , [LastName]) FROM YOURTABLE

0

मैंने एक स्ट्रिंग की कास्टिंग करने की कोशिश की और एक शून्य-लंबाई वाले स्ट्रिंग के लिए परीक्षण किया और यह काम किया।

CASE 
   WHEN LEN(CAST(field_value AS VARCHAR(MAX))) = 0 THEN 
       DO THIS
END AS field 

0

NULL कुछ भी बराबर नहीं करता है। केस स्टेटमेंट मूल रूप से कह रहा है जब मूल्य = NULL .. यह कभी हिट नहीं होगा।
कई सिस्टम संग्रहीत कार्यविधियाँ भी हैं जो आपके सिंटैक्स के साथ गलत तरीके से लिखी गई हैं। Sp_addpullsubscription_agent और sp_who2 देखें।
काश मुझे पता होता कि मैं उन गलतियों के बारे में Microsoft को कैसे बताऊं क्योंकि मैं सिस्टम स्टोर किए गए प्रोक्स को बदलने में सक्षम नहीं हूं।

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