এসকিউএল: কীভাবে কোনও রেকর্ড রয়েছে তা সঠিকভাবে যাচাই করতে হবে


206

কিছু এসকিউএল টিউনিং-সম্পর্কিত ডকুমেন্টেশন পড়ার সময় আমি এটি খুঁজে পেয়েছি:

SELECT COUNT(*) :

  • সারি সংখ্যা গণনা করে।
  • প্রায়শই কোনও রেকর্ডের অস্তিত্ব যাচাই করতে ভুলভাবে ব্যবহার করা হয়।

SELECT COUNT(*)আসলেই কি খারাপ?

কোনও রেকর্ডের অস্তিত্ব যাচাই করার সঠিক উপায় কী?

উত্তর:


251

নিম্নলিখিতগুলির মধ্যে দুটি ব্যবহার করা ভাল:

-- Method 1.
SELECT 1
FROM table_name
WHERE unique_key = value;

-- Method 2.
SELECT COUNT(1)
FROM table_name
WHERE unique_key = value;

প্রথম বিকল্পটি আপনাকে কোনও ফল বা একটি ফলাফল দেয় না, দ্বিতীয় গণনাটি শূন্য বা এক হতে হবে।

আপনি কী ডকুমেন্টেশন ব্যবহার করছেন? যদিও আপনি ভাল পরামর্শটি পড়েছেন, সাম্প্রতিক আরডিবিএমএস-এর বেশিরভাগ ক্যোয়ারী অপ্টিমাইজারগুলি SELECT COUNT(*)যাইহোক অপ্টিমাইজ করে , সুতরাং তত্ত্বের (এবং পুরানো ডাটাবেসগুলিতে) পার্থক্য থাকলেও আপনার অনুশীলনের কোনও পার্থক্য লক্ষ্য করা উচিত নয়।


1
আমি স্পষ্ট করে বলব যে আমি "কী" মান "ধারাটি দিয়ে" অনন্য কী "করতে চেয়েছিলাম তবে তা ছাড়া আমি এখনও আমার উত্তরের পিছনে আছি।
মার্টিন শ্যাপেনডোনক

1
ঠিক আছে. সেই ভিত্তিতে ক্যোয়ারীটি কেবল একটি বা শূন্য রেকর্ডে ফিরে আসবে। বাট: প্রশ্নটি কোনও অনন্য কলামে সীমাবদ্ধ নয়। এছাড়াও: ২ য় ক্যোয়ারী গণনা (1) একটি ব্যবহারিক POV থেকে গণনা (*) এর সমান।
মার্টিন বা

1
প্রশ্নটি বলে "এ রেকর্ডের অস্তিত্ব যাচাই করার সঠিক উপায় কী"। আমি ব্যাখ্যা করেছি যে একক হিসাবে, 1 রেকর্ড হিসাবে। গণনা (*) এবং গণনা (1) এর মধ্যে পার্থক্যটি ইতিমধ্যে আমার উত্তর দ্বারা আচ্ছাদিত। আমি গণনা পছন্দ করি (1) কারণ এটি একটি নির্দিষ্ট আরডিবিএমএস বাস্তবায়নের উপর নির্ভর করে না।
মার্টিন শ্যাচেনডোনক

192

আমি কাউন্ট ফাংশনটি মোটেই ব্যবহার না করাকে পছন্দ করব:

IF [NOT] EXISTS ( SELECT 1 FROM MyTable WHERE ... )
     <do smth>

উদাহরণস্বরূপ আপনি যদি ডাটাবেসে প্রবেশের আগে ব্যবহারকারীর উপস্থিতি আছে কিনা তা পরীক্ষা করতে চান তবে ক্যোয়ারীটি এর মতো দেখতে পাওয়া যাবে:

IF NOT EXISTS ( SELECT 1 FROM Users WHERE FirstName = 'John' AND LastName = 'Smith' )
BEGIN
    INSERT INTO Users (FirstName, LastName) VALUES ('John', 'Smith')
END

উত্সাহতভাবে আমরা এটি ব্যবহার করি (যাচাই করুন) যখন কিছু করতে চান, তবে আপনার উত্তরটি আরও সম্পূর্ণ।
আব্নার এস্কেসিও

টি-এসকিউএল ব্যবহার করে তা উল্লেখ করা ভাল
ব্রোনেক

20

তুমি ব্যবহার করতে পার:

SELECT 1 FROM MyTable WHERE <MyCondition>

শর্তের সাথে মিলে কোনও রেকর্ড না থাকলে, ফলাফল রেকর্ডসেট খালি থাকে।


আপনি কি শীর্ষ 1 বোঝাতে চেয়েছিলেন? -> (মাই টেবিল থেকে প্রথম 1 নির্বাচন করুন <আমার শর্ত>)
জ্যাকব

6
না, আমি হুবহু "1" বলতে
চাইছিলাম

1
ক্যোরি অপটিমাইজারকে এমনকি নওয়ে সক্ষম করতে যে আপনি বাকী ডেটাসেটগুলি পড়বেন না / প্রয়োজন হবে না, আপনার শীর্ষস্থান 1 1 থেকে নির্বাচন করা উচিত ... কোথায় ... (অথবা আপনার আরডিবিএসের জন্য উপযুক্ত কোয়েরি ইঙ্গিতগুলি ব্যবহার করুন)
ইফ্লো

3
অস্টিস্ট অপারেটর নিজেই কেবলমাত্র নিরঙ্কুশতম ন্যূনতম তথ্য পুনরুদ্ধার করার চেষ্টা করে, তাই শীর্ষস্থানীয় 1 এর সংযোজন ক্যোয়ার আকারে 5 টি অক্ষর যুক্ত করা ছাড়া কিছুই করে না। - sqlservercentral.com/blogs/sqlinthewild/2011/04/05/…
অ্যাকোয়াএলেক্স

13

অন্যান্য উত্তরগুলি বেশ ভাল তবে এটি অপ্রয়োজনীয় সারিগুলি পরীক্ষা করা রোধ করতে LIMIT 1(বা সমতুল্য) যুক্ত করাও কার্যকর হবে be


3
যদি কোনও "অস্তিত্বের জন্য চেক" ক্যোয়ারী একাধিক সারিতে ফিরে আসে তবে আমি মনে করি যে ফলাফলের সংখ্যা সীমাবদ্ধ না করে আপনার WHERE ধারাটি দ্বিগুণ করা আরও কার্যকর think
মার্টিন শ্যাপেনডোনক

2
আমার মনে হয় সীমাটি ওরাকলে ব্যবহৃত হয় এস এসকিউএল সার্ভারে নয়
শান্তনু গুপ্ত

7
আমি মামলাটি বিবেচনা করছি যেখানে তারা বৈধভাবে একাধিক সারি হতে পারে - যেখানে প্রশ্নটি রয়েছে: "এই শর্তটি সন্তুষ্ট করে এমন কি (এক বা একাধিক) সারি রয়েছে?" সেক্ষেত্রে আপনি কেবল একটিতে এই সমস্তটি দেখতে চান না।
জেসিডাব্লু

1
@ শান্তানু - আমি জানি, সে কারণেই আমি অন্য রূপগুলি ব্যাখ্যা করে এন.উইকিপিডিয়া নিবন্ধের সাথে লিঙ্ক করেছি।
জেসিডাব্লু

11
SELECT COUNT(1) FROM MyTable WHERE ...

সমস্ত রেকর্ডের মাধ্যমে লুপ হবে। রেকর্ড অস্তিত্বের জন্য এটি ব্যবহার করা খারাপ কারণ।

আমি ব্যবহার করব

SELECT TOP 1 * FROM MyTable WHERE ...

1 রেকর্ড সন্ধানের পরে, এটি লুপটি সমাপ্ত করবে।


ক্ষেত্রে SELECT TOP 1এটি আসলে এক খোঁজার পর বন্ধ করে দেব অথবা এটি সব কোনো একটি শীর্ষ বলে পাবে এটি রেখেছে?
Eirik এইচ

3
PS: নিশ্চিত হতে আমি সর্বদাIF EXISTS (SELECT TOP 1 1 FROM ... WHERE ..)
Eirik এইচ

স্টার অপারেটর ডিবিএমএসকে কেবলমাত্র সূচি (এস) এর পরিবর্তে ক্লাস্টারড সূচক অ্যাক্সেস করতে বাধ্য করবে যা আপনার যোগদানের শর্তের জন্য প্রয়োজন। সুতরাং ফলস্বরূপ একটি ধ্রুবক ভালুয়া ব্যবহার করা ভাল, অর্থাৎ শীর্ষস্থানীয় 1 1 টি নির্বাচন করুন .... এটি 1 বা ডিবি-নুল ফিরে আসবে, শর্তের উপর নির্ভর করে কোনও ম্যাচ কিনা।
eFloh

এটা সুন্দর. আমি প্রথমটা পছন্দ করি।
isxaker

10

তুমি ব্যবহার করতে পার:

SELECT COUNT(1) FROM MyTable WHERE ... 

অথবা

WHERE [NOT] EXISTS 
( SELECT 1 FROM MyTable WHERE ... )

SELECT *আপনি সমস্ত ক্ষেত্রের পরিবর্তে প্রতিটি সারিটির জন্য মান 1 বেছে নিচ্ছেন তাই এটি আরও কার্যকর হবে ।

COUNT (*) এবং COUNT (কলামের নাম) এর মধ্যে একটি সূক্ষ্ম পার্থক্য রয়েছে:

  • COUNT(*) নালগুলি সহ সমস্ত সারি গণনা করবে
  • COUNT(column name)কেবল কলামের নামের নাল ঘটনাগুলি গণনা করবে

2
আপনি একটি ভুল ধারণা তৈরি করছেন যে কোনও ডিবিএমএস কোনওভাবে all সমস্ত কলাম চেক করবে। মধ্যে কর্মক্ষমতা পার্থক্য count(1)এবং count(*)কেবল সবচেয়ে মস্তিষ্ক মৃত DBMS বিভিন্ন হবে।
প্যাক্সডিয়াবল্লো

2
না, আমি বলছি যে আপনি বাস্তবায়নের বিশদগুলিতে আসলে নির্ভর করছেন যখন আপনি বলেন যে এটি আরও দক্ষ হবে। আপনি যদি সত্যিই সেরা পারফরম্যান্স পেয়ে থাকেন তা নিশ্চিত করতে চান, তবে আপনার প্রতিনিধি ডেটা ব্যবহার করে নির্দিষ্ট প্রয়োগের জন্য এটি প্রোফাইল করা উচিত, বা কেবল এটি সম্পূর্ণরূপে ভুলে যাওয়া। অন্য যে কোনও কিছুই সম্ভাব্য বিভ্রান্তিকর, এবং ডিবি 2 থেকে মাইএসকিউএলে যাওয়ার সময় (উদাহরণস্বরূপ) মারাত্মকভাবে পরিবর্তিত হতে পারে।
প্যাক্সডিয়াবল্লো

1
আমি এটা পরিষ্কার করতে চাই যে আমি আপনার উত্তরটি অপসারণ করছি না। এটা তোলে হয় দরকারী। শুধুমাত্র আমি যেহেতু আমরা করেছি দক্ষতা দাবি ইস্যু নেওয়া বিট সম্পন্ন DB2 / Z মধ্যে মূল্যায়ন এবং সেখানে মধ্যে কোনো পার্থক্য খুঁজে পেয়েছিলেন count(*)এবং count(1)অন্য ডিবিএমএসের ক্ষেত্রে সেটাই হোক না কেন, আমি বলতে পারি না।
প্যাক্সিডিয়াবল্লো

3
"অন্য যে কোনও সম্ভাব্য বিভ্রান্তিকর, এবং ডিবি 2 থেকে মাইএসকিউএলে যাওয়ার সময় (উদাহরণস্বরূপ) মারাত্মকভাবে পরিবর্তিত হতে পারে" নির্বাচন 1 (1) প্রয়োগের পার্থক্যের তুলনায় ডিবিএমএসকে সরিয়ে নেওয়ার সময় আপনি নির্বাচন নির্বাচন (*) এর পারফরম্যান্স অবক্ষয়ের দ্বারা কামড়ানোর সম্ভাবনা অনেক বেশি likely বা COUNT (1)। আমি কোডটি লেখার ক্ষেত্রে দৃ firm় বিশ্বাসী যা আপনার পছন্দসই আচরণে ডিফল্টরূপে অপ্টিমাইজার বা সংকলকগুলির উপর নির্ভর না করে আপনি যা অর্জন করতে চান তার সর্বাধিক স্পষ্টভাবে প্রকাশ করে।
উইনস্টন স্মিথ

1
বিভ্রান্তিকর বিবৃতি "COUNT (*)" এর অর্থ 'সারিগুলি গণনা করুন' সম্পূর্ণ স্টপ। এটি কোনও নির্দিষ্ট কলামে অ্যাক্সেসের প্রয়োজন নেই। এবং বেশিরভাগ ক্ষেত্রে এমনকি কোনও অনন্য সূচকই যথেষ্ট হিসাবে গণনা হিসাবে সারিটিতে অ্যাক্সেসের প্রয়োজন হয় না।
জেমস অ্যান্ডারসন

9

তুমি ব্যবহার করতে পার:

SELECT 1 FROM MyTable WHERE... LIMIT 1

select 1অপ্রয়োজনীয় ক্ষেত্রগুলি পরীক্ষা করা রোধ করতে ব্যবহার করুন ।

LIMIT 1 অপ্রয়োজনীয় সারিগুলি পরীক্ষা করা রোধ করতে ব্যবহার করুন ।


3
গুড পয়েন্ট তবে সীমাবদ্ধতা মাইএসকিউএল এবং পোস্টগ্রিএসকিউএল নিয়ে কাজ করে, শীর্ষস্থানীয় এসকিউএল সার্ভারে কাজ করে, আপনার উত্তরটি এটি নোট করা উচিত
লিও গুর্দিয়ান

0

আমি এইভাবে ব্যবহার করছি:

IIF(EXISTS (SELECT TOP 1 1 
                FROM Users 
                WHERE FirstName = 'John'), 1, 0) AS DoesJohnExist

0

অন্যান্য বিকল্প:

SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [MyTable] AS [MyRecord])
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.