এসকিউএল - একটি টেবিল থেকে রেকর্ড সন্ধান করুন যা অন্যটিতে নেই


310

আমি নিম্নলিখিত দুটি এসকিউএল টেবিল পেয়েছি (মাইএসকিউএল এ):

Phone_book
+----+------+--------------+
| id | name | phone_number |
+----+------+--------------+
| 1  | John | 111111111111 |
+----+------+--------------+
| 2  | Jane | 222222222222 |
+----+------+--------------+

Call
+----+------+--------------+
| id | date | phone_number |
+----+------+--------------+
| 1  | 0945 | 111111111111 |
+----+------+--------------+
| 2  | 0950 | 222222222222 |
+----+------+--------------+
| 3  | 1045 | 333333333333 |
+----+------+--------------+

আমি কীভাবে জানতে পারি যে কোন কলগুলি সেই ব্যক্তিদের দ্বারা করা হয়েছিল যাদের phone_numberমধ্যে নেই Phone_book? কাঙ্ক্ষিত আউটপুট হবে:

Call
+----+------+--------------+
| id | date | phone_number |
+----+------+--------------+
| 3  | 1045 | 333333333333 |
+----+------+--------------+

কোন সাহায্যের অনেক প্রশংসা হবে।

উত্তর:


438

আপনার ক্যোয়ারী অপটিমাইজারটি কতটা ভাল, এবং আপনার দুটি টেবিলের আপেক্ষিক আকারের উপর নির্ভর করে বিভিন্ন দক্ষতার সাথে এটি করার বিভিন্ন উপায় রয়েছে:

এটি সবচেয়ে সংক্ষিপ্ত বিবৃতি এবং আপনার ফোন বইটি খুব ছোট হলে খুব দ্রুত হতে পারে:

SELECT  *
FROM    Call
WHERE   phone_number NOT IN (SELECT phone_number FROM Phone_book)

বিকল্পভাবে ( আল্টার লাইফকে ধন্যবাদ )

SELECT *
FROM   Call
WHERE  NOT EXISTS
  (SELECT *
   FROM   Phone_book
   WHERE  Phone_book.phone_number = Call.phone_number)

বা (ডব্লিউওপিআরকে ধন্যবাদ)

SELECT * 
FROM   Call
LEFT OUTER JOIN Phone_Book
  ON (Call.phone_number = Phone_book.phone_number)
  WHERE Phone_book.phone_number IS NULL

(এটিকে উপেক্ষা করুন, যেমনটি অন্যেরা বলেছেন, সাধারণত যে কলামগুলি আপনি চান তা নির্বাচন করা সবচেয়ে ভাল ' *')


1
IN এড়ান, উপস্থিতি ব্যবহার করুন - ইঙ্গিতটি প্রশ্নের শিরোনামে রয়েছে
অন্নাকাটা

28
বাম বাহিরের জোড়টি সম্ভবত সাধারণ ক্ষেত্রে দ্রুততম কারণ এটি সাবকোরির পুনরাবৃত্তি কার্যকর করতে বাধা দেয়।
ডব্লিউওপিআর

পিক হতে হবে না, তবে আমার পরামর্শ অনুসারে সাবকিউরিটি <কোড> নির্বাচন করুন 'x' </code> নির্বাচন করুন এবং <কোড> নির্বাচন করবেন না </ কোড>
অল্টার লাইফ

হ্যাঁ - মাইএসকিউএল ম্যানুয়াল দাড়ায় যে এই একটি স্বাভাবিক হল 'বিদ্যমান' QUERY
ঊষা

2
@ অ্যালনিটক: দ্বিতীয় ক্যোয়ারিতে আপনাকে SELECT *সাবকোয়রিতে দরকার নেই। পরিবর্তে, উদাহরণস্বরূপ, SELECT 1যথেষ্ট যথেষ্ট হওয়া উচিত।
আলেকজান্ডার আবাকুমভ

90
SELECT Call.ID, Call.date, Call.phone_number 
FROM Call 
LEFT OUTER JOIN Phone_Book 
  ON (Call.phone_number=Phone_book.phone_number) 
  WHERE Phone_book.phone_number IS NULL

কোয়েরি অপ্টিমাইজারকে এর যাদুতে কাজ করার অনুমতি দিয়ে সাবকোয়ারিটি সরানো উচিত।

এছাড়াও, "নির্বাচন করুন" এড়ান কারণ কেউ যদি অন্তর্নিহিত সারণী বা দর্শনগুলি পরিবর্তন করে (এবং এটি অক্ষম) তবে এটি আপনার কোডটি ভেঙে দিতে পারে।


10
এটি দ্বিতীয়তম টেবিলে একাধিক পাস সম্পাদন করে না বলে এটি সাধারণত সর্বাধিক দক্ষ পদ্ধতি ... আশা করি কিছু লোক কমেটগুলি পড়ছে।
Nerdfest

3
আমি বরং আশা করি লোকেদের প্রোফাইল: আপনি যদি শীর্ষস্থানীয় এসকিউএল পারফরম্যান্স গুরু না হন তবে দ্রুততম কোনটি হবে তা আগাম জানিয়ে দেওয়া (এবং আপনি যে ডিবিএমএস ইঞ্জিন ব্যবহার করেন তার উপর নির্ভর করে)।
bortzmeyer

2
এই ক্ষেত্রে দ্রুততম হওয়ার জন্য আপনি কী আশা করতে পারেন তা সহজেই আপনাকে জানিয়ে দেবে বিগ ও স্বরলিপি এটি বিশালতার অর্ডার আলাদা।
জোন্সোপলিস

আপনার দুটি টেবিলের মধ্যে যদি কোনও সম্পর্ক থাকে তবে সেখানে পরকালের উত্তর এবং আমার মন্তব্য দেখুন 1:N। বা ভ্লাদোর জবাবDISTINCT হিসাবে দেখা হিসাবে যুক্ত করুন
স্টেভ

25

বৃহত্তর ডেটাসেটের সাথে কাজ করার সময় উপরের উত্তরগুলির তুলনায় নীচের কোডটি কিছুটা দক্ষ হবে।

SELECT * FROM Call WHERE 
NOT EXISTS (SELECT 'x' FROM Phone_book where 
Phone_book.phone_number = Call.phone_number)

1
সর্বদা হিসাবে, সেরা পারফরম্যান্সের সাথে একটিটি বেছে নিতে আপনার টার্গেট ডেটাসেটের বিরুদ্ধে ক্যোয়ারির কার্য সম্পাদনকে প্রোফাইল করা উপযুক্ত। এসকিউএল অপ্টিমাইজারগুলি এই দিনগুলিতে যথেষ্ট ভাল যে পারফরম্যান্সের ফলাফলগুলি প্রায়শই অবাক করে।
গ্রেগ হিউগিল

1
এই পদ্ধতির একটি সুবিধা (বনাম ডাব্লুপিটি আউটরের সাথে ডাব্লুওপিআর যোগ দিন) হ'ল এটি Callযদি একাধিক সারি সারি থাকে তবে সারি প্রতি একাধিক সারি ফেরানো এড়ানো হবে Phone_book। অর্থাত্ যদি 1:Nআপনার দুটি টেবিলের মধ্যে সম্পর্ক থাকে।
টুলমেকারস্টেভ

আমি এটির সাথেই শুরু করব - এটি সরাসরি অভিপ্রায় উপস্থাপন করে। পারফরম্যান্স যদি যথেষ্ট পরিমাণে ভাল না হয় তবে নিশ্চিত হয়ে নিন যে উপযুক্ত সূচি রয়েছে। তারপরেই, কম-সুস্পষ্ট চেষ্টা করুন LEFT OUTER JOIN, দেখুন এটির অভিনয় আরও ভাল।
নির্মাতা স্টিভ

6
SELECT DISTINCT Call.id 
FROM Call 
LEFT OUTER JOIN Phone_book USING (id) 
WHERE Phone_book.id IS NULL

এটি আপনার ফোন_বুকের টেবিলে অনুপস্থিত অতিরিক্ত আইডি-গুলি ফিরিয়ে দেবে।


4

আমি মনে করি

SELECT CALL.* FROM CALL LEFT JOIN Phone_book ON 
CALL.id = Phone_book.id WHERE Phone_book.name IS NULL

idকলাম callটেবিল হিসাবে একই মান নয় idকলাম Phone_bookযাতে আপনি এই মান এ যোগ করতে পারবেন না, টেবিল। অনুরূপ পদ্ধতির জন্য ডাব্লুওপিআর এর উত্তর দেখুন।
মাইকেল ফ্রেড্রিকসন

3
SELECT t1.ColumnID,
CASE 
    WHEN NOT EXISTS( SELECT t2.FieldText  
                     FROM Table t2 
                     WHERE t2.ColumnID = t1.ColumnID) 
    THEN t1.FieldText
    ELSE t2.FieldText
END FieldText       
FROM Table1 t1, Table2 t2

একই কলামের জন্য অন্য টেবিলে ডেটা উপস্থিত না থাকলে এটি আপনাকে এক টেবিল থেকে তথ্য ফিরিয়ে দেবে
হরবিন্দার সিধু

1
SELECT name, phone_number FROM Call a
WHERE a.phone_number NOT IN (SELECT b.phone_number FROM Phone_book b)

এটি প্রশ্নের উত্তর সরবরাহ করে না। কোনও লেখকের কাছ থেকে সমালোচনা বা স্পষ্টতার জন্য অনুরোধ জানাতে, তাদের পোস্টের নীচে একটি মন্তব্য দিন। - পর্যালোচনা থেকে
ডেনিস ক্রিচেল

@ ডেনিসক্রিচেল কোয়েরি আপডেট করেছেন যাতে এটি প্রশ্নের সাথে আরও সুনির্দিষ্ট হয়।
JoshYates1980

1

অন্যথা,

select id from call
minus
select id from phone_number

1
নিশ্চিত নয় যে এই প্রশ্নের উত্তর যেমন রয়েছে (যদিও MINUS) অপারেটরটি একটি নতুন সংযোজন। এটি নিম্ন মানের সারিতে শেষ হয়েছে - আপনি এই উত্তরটি বাড়িয়ে দিতে পছন্দ করতে পারেন।
ফু ফু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.