টি-এসকিউএল CASE ধারা: কখন কীভাবে নির্দিষ্ট করা যায়


227

আমি এটির মতো একটি টি-এসকিউএল স্টেটমেন্ট লিখেছি (মূলটি দেখতে অন্যরকম তবে আমি এখানে একটি সহজ উদাহরণ দিতে চাই):

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

এই বিবৃতিতে কোনও সিনট্যাক্স ত্রুটি নেই তবে কেস-ক্লজ সর্বদা ELSE- অংশটি বেছে নেয় - শেষের নামটি শূন্য থাকলেও। কিন্তু কেন?

আমি যা করতে চাই তা হল প্রথম নাম এবং সর্বশেষ নামটি একত্রিত করা, তবে শেষ নামটি যদি বাতিল হয় তবে পুরো নামটি বাতিল হয়ে যায়:

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 (শেষ নাম, '') কেস স্টেটমেন্টটি সংক্ষিপ্ত আকারে হলেও বড় প্রশ্নগুলির ক্ষেত্রে কয়েলেসের চেয়ে কম রক্ষণাবেক্ষণযোগ্য। শেষ পর্যন্ত, আপনার একই ফলাফল রয়েছে। আপনার যদি অনুকূলিতকরণ প্রয়োজন হয়, কার্যকর করার পরিকল্পনাগুলি পরীক্ষা করুন তবে আমি খুব বেশি পার্থক্য লক্ষ্য করিনি।
অ্যান্টনি ম্যাসন

1
COALESCEমূলত অভ্যন্তরীণভাবে অনুবাদ করে CASE। CASE এর সমস্যাটি last_nameহ'ল দুবার মূল্যায়ন করা হয় এবং এটি অন্যান্য পার্শ্ব প্রতিক্রিয়া হতে পারে - এই দুর্দান্ত নিবন্ধটি দেখুন । যা জিজ্ঞাসিত হয়েছিল তা সমাধান করতে, আমি বরং নীচের মন্তব্যেISNULL(' '+ last_name, '') উল্লিখিত সাথে যেতে চাই ।
মিরোক্লাভ

41

WHEN অংশটি == এর সাথে তুলনা করা হলেও আপনি সত্যিই NULL এর সাথে তুলনা করতে পারবেন না। চেষ্টা

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

পরিবর্তে বা সংযুক্তি:

COALESCE(' '+last_name,'')

('' + সর্বশেষ নামটি NUL হয় যখন শেষ নামটি NULL হয়, সুতরাং সেই ক্ষেত্রে এটি ফিরে আসা উচিত ')


ঠিক আছে, WHEN অংশে == সহ তথ্যের জন্য আপনাকে ধন্যবাদ। আমি এটা জানতাম না। COALESCE এর সাথে এটিও সূক্ষ্মভাবে কাজ করে। ভেবে দেখেনি যে এত কিছু করার সম্ভাবনা আছে।
মেনি

15

প্রচুর সমাধান রয়েছে তবে আসল বিবৃতিটি কেন কাজ করে না তা কোনওটিই জুড়ে না।

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

সাম্যের পরে, সাম্যের জন্য একটি চেক আছে, যা সত্য বা মিথ্যা হওয়া উচিত।

যদি তুলনার একটি বা উভয় অংশই শূন্য হয়, তবে তুলনার ফলাফলটি অজানা হবে, যা কেস কাঠামোর ক্ষেত্রে মিথ্যা বলে গণ্য করা হয়। দেখুন: 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
সর্বশেষ নামটি শূন্য হলে এটি অপ্রয়োজনীয় স্থান যুক্ত করে, যা ওপি এড়াতে চেষ্টা করেছিল was
মার্সেলো ক্যান্টোস

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

এটি স্থানটি সর্বশেষ নামের সাথে যুক্ত করে, যদি এটি শূন্য হয় তবে পুরো স্থান + শেষ নামটি NUL এ যায় এবং আপনি কেবল একটি প্রথম নাম পান, অন্যথায় আপনি একটি ফার্ম + স্থান + পদবি পেয়েছেন।

নাল স্ট্রিং সহ কনকেন্টেশন করার জন্য এটি ডিফল্ট সেটিংটি যতক্ষণ কাজ করবে:

SET CONCAT_NULL_YIELDS_NULL ON 

OFFএসকিউএল সার্ভারের ভবিষ্যতের সংস্করণগুলিতে মোডটি চলে যাওয়ার পরে এটি উদ্বেগের বিষয় হওয়া উচিত নয়


4

সমস্যাটি হল এই যে শূন্য এমনকি নিজেই না কিছু সমান হতে বিবেচনা করা হয় না, কিন্তু অদ্ভুত অংশ যে হয় না নিজেই সমান।

নিম্নলিখিত বিবৃতিগুলি বিবেচনা করুন (যা এসকিউএল সার্ভার টি-এসকিউএলে বিটিডব্লিউ অবৈধ তবে এটি মাই-এসকিউএলে বৈধ, তবে এটি এএনএসআই নালকে সংজ্ঞায়িত করে এবং এসকিউএল সার্ভারে কেস স্টেটমেন্ট ইত্যাদি ব্যবহার করে যাচাই করা যায়)

SELECT NULL = NULL -- Results in NULL

SELECT NULL <> NULL -- Results in NULL

সুতরাং প্রশ্নের সঠিক / মিথ্যা উত্তর নেই, পরিবর্তে উত্তরটিও নালাগুলি।

এটিতে অনেকগুলি অন্তর্ভুক্ত রয়েছে, উদাহরণস্বরূপ

  1. ক্ষেত্রে বিবৃতি, যা যে কোন নাল মান সবসময় Else clause ব্যবহার করবে যদি না আপনি স্পষ্টভাবে ব্যবহার করেন, তখন শূন্য অবস্থায় (IS না শর্ত )WHEN NULL
  2. স্ট্রিং সংক্ষিপ্তকরণ, হিসাবে
    SELECT a + NULL -- Results in NULL
  3. যেখানে বা যেখানে শর্তে নেই, এমন কোনও ক্ষেত্রে যেমন আপনি সঠিক ফলাফল চান তা নিশ্চিত করে যে কোনও নাল মান ফিল্টার করার জন্য সংযুক্ত সাব-কোয়েরিতে নিশ্চিত করুন।

কেউ এসকিউএল সার্ভারে উল্লেখ করে এই আচরণকে ওভাররাইড করতে পারে SET ANSI_NULLS OFF, তবে এটি প্রস্তাবিত নয় এবং এটি করা উচিত নয় কারণ এটি অনেকগুলি সমস্যার কারণ হতে পারে, কেবলমাত্র স্ট্যান্ডার্ডের বিচ্যুতির কারণে।

(পার্শ্ব নোট হিসাবে, মাই-এসকিউএলে <=>নাল তুলনার জন্য একটি বিশেষ অপারেটর ব্যবহার করার বিকল্প রয়েছে ))

তুলনায়, সাধারণ প্রোগ্রামিং ভাষাগুলিতে নালকে একটি নিয়মিত মান হিসাবে বিবেচনা করা হয় এবং এটি নিজের সমান হয়, তবে এটি NAN মান যা নিজের সাথেও সমান নয়, তবে এটি নিজের সাথে তুলনা করার সময় অন্তত এটি 'মিথ্যা' প্রত্যাবর্তন করে, (এবং সমান না হিসাবে পরীক্ষা করার সময় বিভিন্ন প্রোগ্রামিং ভাষার বিভিন্ন প্রয়োগ রয়েছে)।

তবে লক্ষ করুন যে বেসিক ভাষায় (যেমন VB ইত্যাদি) কোনও 'নাল' কীওয়ার্ড নেই এবং এর পরিবর্তে কেউ 'কিছুই না' কীওয়ার্ড ব্যবহার করে যা সরাসরি তুলনায় ব্যবহার করা যায় না এবং এর পরিবর্তে এসকিউএল হিসাবে 'আইএস' ব্যবহার করা দরকার, তবে এটি বাস্তবে নিজের সমান (অপ্রত্যক্ষ তুলনা ব্যবহার করার সময়)।


1
"আশ্চর্যের অংশটি এটিও নিজের সমান নয়" " => এটি বিবেচনা করে আশ্চর্যজনক নয় যে এসকিউএল এর নালটির অর্থ 'অজানা' রয়েছে। কিছু অজানা, সম্ভবত অজানা অন্য কোনও কিছুর মতো নয়।
জেডিসি


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মূল্যায়ন করবে এবং প্রত্যাশার মতো '' ফিরিয়ে দেবে।

আমি আশা করি এটি একটি সহায়ক বিকল্প।

আমি স্কেল সার্ভার ২০০৮ এবং তারপরের জন্য এই পরীক্ষার কেসটি অন্তর্ভুক্ত করেছি:

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) নুল ফেরায়, 0 নয়
জেসন মুসগ্রোভ

পোকেচু 22 সঠিক, এবং এটিই সংশোধিত লিপি: CASE LEN (ISNULL (সর্বশেষ নাম, '')) যখন 0 তম '' ELSE '' + শেষ_নাম শেষ হিসাবে newlastName
শেফ

0

জেসন একটি ত্রুটি পেয়েছে, সুতরাং এটি কাজ করে ...

অন্য প্ল্যাটফর্মের সংস্করণগুলি কি কেউ নিশ্চিত করতে পারেন?
SQL সার্ভার:

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

আপনি ইসনুল ফাংশন ব্যবহার করতে পারেন

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

যদি একটি কলাম শূন্য হয় আপনি একটি খালি চর পাবেন

মাইক্রোসফ্ট এসকিউএল সার্ভার ২০০+ এর সাথে সামঞ্জস্যপূর্ণ


0

এসকিউএল সার্ভার ২০১২-এর পরে উপলব্ধ কনক্যাট ফাংশনটি ব্যবহার করুন।

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 কোন কিছুর সমান হয় না। কেস স্টেটমেন্টটি মূলত বলছে যখন মান = নুল .. এটি কখনই আঘাত করবে না।
এছাড়াও বেশ কয়েকটি সিস্টেম সঞ্চিত পদ্ধতি রয়েছে যা আপনার সিনট্যাক্সের সাথে ভুলভাবে লেখা হয়েছে। Sp_addpullsubscription_agent এবং sp_Wo2 দেখুন।
আশা করি আমি কীভাবে মাইক্রোসফ্টকে এই ভুলগুলি সম্পর্কে অবহিত করতে জানতাম কারণ আমি সিস্টেম সঞ্চিত প্রকল্পগুলি পরিবর্তন করতে পারছি না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.