মাইএসকিউএল "না ইন ইন" ক্যোয়ারী


181

Table1মূল সারণীর মান অন্য সারণীতে ( Table2) একটি কলামে উপস্থিত নেই এমন সমস্ত সারি সরাতে আমি একটি সাধারণ ক্যোয়ারী চালাতে চেয়েছিলাম ।

আমি ব্যবহার করার চেষ্টা করেছি:

SELECT * FROM Table1 WHERE Table1.principal NOT IN Table2.principal

এটি পরিবর্তে একটি সিনট্যাক্স ত্রুটি নিক্ষেপ করছে। গুগল অনুসন্ধান আমাকে এমন ফোরামে নিয়ে গেছে যেখানে লোকেরা বলেছিল যে মাইএসকিউএল সমর্থন করে না NOT INএবং অত্যন্ত জটিল কিছু ব্যবহার করা দরকার। এটা কি সত্য? নাকি আমি ভয়াবহ ভুল করছি?


1
এবং যদি আমি তিনটি টেবিল থেকে অনুরূপ ডেটা চাই। আমি বলতে চাইছি একটি টেবিল 1 এ 2000 এন্ট্রি রয়েছে, অন্য দুটি টেবিল 2 এবং 3 টিতে 500 টি এন্ট্রি আছে, তাদের সবকটিরই সাধারণ ক্ষেত্রের 'নাম' রয়েছে। 'নাম' এর উপর ভিত্তি করে টেবিল 1 এবং 3 তে উপস্থিত না থাকা সারণী 1 থেকে আমরা কীভাবে সমস্ত বিবরণ পেতে পারি? আমরা কি দুবার নট ইন ব্যবহার করতে পারি, যদি হয় তবে ..?

উত্তর:


310

IN ব্যবহার করতে, আপনার অবশ্যই একটি সেট থাকতে হবে, পরিবর্তে এই সিনট্যাক্সটি ব্যবহার করুন:

SELECT * FROM Table1 WHERE Table1.principal NOT IN (SELECT principal FROM table2)

85
যত্নশীল যখন table2.principalহতে পারে NULL। যে ক্ষেত্রে NOT INসবসময় ফিরে আসবে FALSEকারণ NOT INহিসাবে গণ্য হবে <> ALL, যা মত subquery থেকে সব সারি তুলনা Table1.principal <> table2.principal, যা যখন সঙ্গে তুলনা ব্যর্থ NULL: Table1.principal <> NULLফলস্বরুপ হতে পারে না TRUE। ঠিক করার জন্য: NOT IN (SELECT principal FROM table2 WHERE principal IS NOT NULL)
বস্টি

4
মন্তব্যের জন্য ধন্যবাদ বাসতি! কেন জিজ্ঞাসাটি আশানুরূপ কাজ করছে না তা বোঝার চেষ্টা করে অনেক সময় ব্যয় করলেন।
gva

3
'নির্বাচন করুন' তালিকার ভিতরে 'নির্বাচন করুন' ব্যবহার এড়াতে ভুলবেন না। আপনাকে অবশ্যই একটি নির্দিষ্ট কলাম নির্বাচন করতে হবে। অন্যথায় আপনি এই ত্রুটিটি পেয়ে যাবেন: stackoverflow.com/questions/14046838/…
লরিয়ান ব্রুন

165

সাবকিউরিয়ের বিকল্পটি ইতিমধ্যে উত্তর দেওয়া হয়েছে, তবে নোট করুন যে অনেক ক্ষেত্রে একটি LEFT JOINএটি করার একটি দ্রুত উপায় হতে পারে:

SELECT table1.*
FROM table1 LEFT JOIN table2 ON table2.principal=table1.principal
WHERE table2.principal IS NULL

এটি কোনও টেবিলে উপস্থিত নেই তা নিশ্চিত করতে যদি আপনি একাধিক টেবিল চেক করতে চান (যেমন এসআরকেআর এর মন্তব্যে), আপনি এটি ব্যবহার করতে পারেন:

SELECT table1.*
FROM table1
LEFT JOIN table2 ON table2.name=table1.name
LEFT JOIN table3 ON table3.name=table1.name
WHERE table2.name IS NULL AND table3.name IS NULL

2
আমার নিজের পরীক্ষা এ উভয় জন্য একই কর্মক্ষমতা ছিল NOT IN& LEFT JOIN। +1 উভয়ই
বাফার স্ট্যাক

কোয়েরি একবার দৌড়ে গেলে একবার অভ্যন্তরীণ ডিবি ক্যাশিংয়ের কারণে আপনার একই ফলাফল পাওয়া উচিত
টুটো

আমার জন্য পারফরম্যান্সটি বেশ ভাল ছিল। আমি বিভিন্ন টেবিল দিয়ে দৌড়েছি, যখন তাদের বিদেশী কীগুলি সেট ছিল।
কিনোরা ফ্লাফবল

36

মাইএসকিউএল-এ নয়, বনাম উপস্থিত নেই বনাম বাম জোট / শুভ নয়

মাইএসকিউএল, পাশাপাশি এসকিউএল সার্ভার ব্যতীত অন্যান্য সমস্ত সিস্টেম মেশানো মানটি পাওয়া মাত্রই ফিরে আসতে অনুকূলিত করতে LEFT JOIN/IS NULL সক্ষম করতে সক্ষম হয়েছে FALSEএবং এটিই একমাত্র সিস্টেম যা এই আচরণটি নথিভুক্ত করার যত্ন নিয়েছিল। […] যেহেতু মাইএসকিউএল অ্যালগরিদমগুলি ব্যবহার HASHএবং MERGEযোগদান করতে সক্ষম নয় , কেবলমাত্র ANTI JOINএটি সক্ষম isNESTED LOOPS ANTI JOIN

[...]

মূলত, [ NOT IN] ঠিক একই পরিকল্পনা যে LEFT JOIN/ IS NULLব্যবহারসমূহ, আসলে সত্ত্বেও এই পরিকল্পনা কোডের বিভিন্ন শাখা দ্বারা মৃত্যুদন্ড কার্যকর করা হয় এবং তারা ফলাফলে বিভিন্ন চেহারা EXPLAIN। অ্যালগরিদম আসলে বাস্তবে একই এবং কোয়েরি একই সময়ে সম্পূর্ণ হয়।

[...]

[ব্যবহারের সময় পারফরম্যান্স ড্রপ NOT EXISTS] এর সঠিক কারণ বলা শক্ত , যেহেতু এই ড্রপটি লিনিয়ার এবং উভয় ক্ষেত্রকে সূচিযুক্ত করা না হওয়া পর্যন্ত উভয় টেবিলের মান সংখ্যা ইত্যাদির উপর ডেটা বিতরণের উপর নির্ভর করে না বলে মনে হয়। যেহেতু মাইএসকিউএল-তে তিনটি কোড রয়েছে যা একটি কাজ করে অত্যাবশ্যক, তাই সম্ভবত দায়বদ্ধ কোডটি EXISTSকিছুটা অতিরিক্ত চেক তৈরি করে যা অতিরিক্ত সময় নেয়।

[...]

মাইএসকিউএল একটি ধরণের করতে তিনটি পদ্ধতিই অনুকূলিত করতে পারে NESTED LOOPS ANTI JOIN। […] তবে, এই তিনটি পদ্ধতি তিনটি পৃথক পরিকল্পনা উত্পন্ন করে যা তিনটি পৃথক কোডের দ্বারা কার্যকর করা হয়। EXISTSপ্রিডিকেট কার্যকর করে এমন কোডটি প্রায় 30% কম দক্ষ […]

এজন্য মাইএসকিউএল-এ মূল্যবোধ হারিয়ে যাওয়ার সর্বাধিক উপায় হ'ল একটি LEFT JOIN/ IS NULLবা NOT INতার চেয়ে বেশি ব্যবহার NOT EXISTS

(জোর দেওয়া যুক্ত)


7

দুর্ভাগ্যক্রমে এটি "নট ইন" ধারাটির মাইএসকিউএল ব্যবহারের সাথে একটি সমস্যা বলে মনে হচ্ছে, নীচের স্ক্রিন-শটটি ভুল ফলাফল প্রত্যাবর্তন করে সাব-কোয়েরি বিকল্পটি দেখায়:

mysql> show variables like '%version%';
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| innodb_version          | 1.1.8                        |
| protocol_version        | 10                           |
| slave_type_conversions  |                              |
| version                 | 5.5.21                       |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86_64                       |
| version_compile_os      | Linux                        |
+-------------------------+------------------------------+
7 rows in set (0.07 sec)

mysql> select count(*) from TABLE_A where TABLE_A.Pkey not in (select distinct TABLE_B.Fkey from TABLE_B );
+----------+
| count(*) |
+----------+
|        0 |
+----------+
1 row in set (0.07 sec)

mysql> select count(*) from TABLE_A left join TABLE_B on TABLE_A.Pkey = TABLE_B.Fkey where TABLE_B.Pkey is null;
+----------+
| count(*) |
+----------+
|      139 |
+----------+
1 row in set (0.06 sec)

mysql> select count(*) from TABLE_A where NOT EXISTS (select * FROM TABLE_B WHERE TABLE_B.Fkey = TABLE_A.Pkey );
+----------+
| count(*) |
+----------+
|      139 |
+----------+
1 row in set (0.06 sec)

mysql> 

7

যত্নবান হোন NOT INএটির জন্য কোনও নাম নয় <> ANY, তবে <> ALL!

http://dev.mysql.com/doc/refman/5.0/en/any-in-some-subqueries.html

SELECT c FROM t1 LEFT JOIN t2 USING (c) WHERE t2.c IS NULL

ক্যান 'দ্বারা প্রতিস্থাপন করা

SELECT c FROM t1 WHERE c NOT IN (SELECT c FROM t2)

আপনার অবশ্যই ব্যবহার করা উচিত

SELECT c FROM t1 WHERE c <> ANY (SELECT c FROM t2)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.