মাইএসকিউএল-এ ফুল আউটর জয়েন কীভাবে করবেন?


654

আমি মাইএসকিউএলে একটি সম্পূর্ণ আউটার জয়েন করতে চাই। এটা কি সম্ভব? মাইএসকিউএল দ্বারা সমর্থিত একটি পূর্ণ আউটার যোগদান কি?



4
এই প্রশ্নের আরও ভাল উত্তর আছে
জুলিও মেরিন্স

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

আপনি যখন নন-প্রাথমিক কী / গোষ্ঠীভুক্ত কলামগুলি দ্বারা যোগদানের চেষ্টা করছেন তখন কী হবে? যেমন আমার প্রতি রাজ্য "রাজ্য", "বিক্রয়" এবং প্রতি রাজ্যের "রাজ্য", "ব্যয়" ব্যয়ের আরও একটি প্রশ্ন রয়েছে, উভয় প্রশ্নের ("রাষ্ট্র") দ্বারা গোষ্ঠী ব্যবহার করা হয়েছে। আমি যখন বাম এবং ডানের মধ্যে ইউনিয়ন করি তখন দুটি ক্যোয়ারির সাথে মিলিত হয় আমি বিক্রয় দিয়ে কিছু সারি পাই তবে কোনও ব্যয় হয় না, ব্যয় সহ আরও কয়েকটি কিন্তু বিক্রয় হয় না, সবকিছু ঠিক এই পয়েন্ট পর্যন্ত, তবে আমি উভয়ের সাথেও কয়েকটি পাই বিক্রয় এবং ব্যয় এবং একটি পুনরাবৃত্তি "রাষ্ট্র" কলাম ... খুব বেশি সমস্যা নয় তবে সঠিক মনে হচ্ছে না ...
জায়রো লোজনো

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

উত্তর:


669

আপনার মাইএসকিউএলে সম্পূর্ণ যোগদান নেই, তবে আপনি অবশ্যই সেগুলি অনুকরণ করতে পারবেন ।

একটি কোডের জন্য SAMPLE এই এই প্রশ্ন থেকে প্রতিলিপি আপনার কাছে রয়েছে:

দুটি সারণী টি 1, টি 2 সহ:

SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id

উপরের ক্যোয়ারীটি বিশেষ ক্ষেত্রে কাজ করে যেখানে পুরো আউট জয়েন অপারেশনটিতে কোনও সদৃশ সারি তৈরি হয় না। উপরের UNIONক্যোয়ারী কোয়েরি প্যাটার্ন দ্বারা প্রবর্তিত সদৃশ সারিগুলি সরানোর জন্য সেট অপারেটরের উপর নির্ভর করে । আমরা দ্বিতীয় ক্যোয়ারির জন্য একটি অ্যান্টি-জয়েন প্যাটার্ন ব্যবহার করে সদৃশ সারিগুলির পরিচয় এড়াতে পারি এবং তারপরে দুটি সেট একত্রিত করতে একটি ইউনিয়ন সমস্ত সেট অপারেটর ব্যবহার করি। আরও সাধারণ ক্ষেত্রে, যেখানে পুরো আউটয়ার জয়েন সদৃশ সারিগুলি ফিরিয়ে দেয়, আমরা এটি করতে পারি:

SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION ALL
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
WHERE t1.id IS NULL

33
আসলে আপনি যা লিখেছেন তা সঠিক নয়। কারণ আপনি যখন ইউনিয়ন করবেন তখন আপনি সদৃশগুলি সরিয়ে ফেলবেন এবং কখনও কখনও আপনি যখন দুটি ভিন্ন সারণিতে যোগদান করেন তখন সেখানে নকল থাকতে হবে।
পাভলে লেকিক

158
এটি সঠিক উদাহরণ:(SELECT ... FROM tbl1 LEFT JOIN tbl2 ...) UNION ALL (SELECT ... FROM tbl1 RIGHT JOIN tbl2 ... WHERE tbl1.col IS NULL)
পাভলে লেকিক

8
সুতরাং পার্থক্যটি হ'ল আমি একটি বাম ইনক্লুসিভ জয়েন করছি এবং তারপরে ডান এক্সক্লুসিভ
ইউএনআইএন

5
এবং আমি এখন দেখছি যে আপনি নিজেরাই বলছেন, দুঃখিত। সম্ভবত আপনি নিজের উত্তরটি আপডেট করতে পারেন, এই ক্ষেত্রে যদি এটি ভুল হয়ে যায় এবং ইউনিয়ন সবসময় আরও কার্যকর হতে চলেছে তবে তা দেওয়া যেতে পারে?
ysth

10
@ টিপিক्यूब: যদি কোনও সদৃশ সারি থাকে না t1এবং t2, এই উত্তরের ক্যোয়ারী এমন একটি রেজাল্ট দেয় যা সম্পূর্ণ আউট জয়েনকে এমুলেট করে। তবে আরও সাধারণ ক্ষেত্রে, উদাহরণস্বরূপ, নির্বাচিত তালিকায় প্রত্যাবর্তিত সারিগুলি অনন্য করে তুলতে পর্যাপ্ত কলাম / এক্সপ্রেশন থাকে না, তবে এই ক্যোয়ারী বিন্যাসটি এটি দ্বারা উত্পাদিত সেটটি পুনরুত্পাদন করার জন্য পর্যাপ্ত নয়FULL OUTER JOIN । আরও বিশ্বস্ত এমুলেশন পেতে, আমাদের একটি UNION ALLসেট অপারেটর প্রয়োজন , এবং যে কোনও প্রশ্নের জন্য একটি অ্যান্টি-জয়েন্ট প্যাটার্ন প্রয়োজন। পাভেল লেকিকের (উপরে) মন্তব্যটি সঠিক কোয়েরি প্যাটার্ন দেয় ।
spencer7593

350

উত্তর যে পাবলো সান্তা ক্রুজ দিয়েছে তা সঠিক; যাইহোক, যদি কেউ এই পৃষ্ঠাতে হোঁচট খায় এবং আরও ব্যাখ্যা চান, তবে এখানে একটি বিশদ বিচ্ছেদ।

উদাহরণ সারণী

ধরুন আমাদের নীচের সারণি রয়েছে:

-- t1
id  name
1   Tim
2   Marta

-- t2
id  name
1   Tim
3   Katarina

অভ্যন্তরীণ যোগদান

একটি অভ্যন্তরীণ যোগদান, এর মতো:

SELECT *
FROM `t1`
INNER JOIN `t2` ON `t1`.`id` = `t2`.`id`;

আমাদের উভয় সারণীতে প্রদর্শিত কেবল রেকর্ডগুলি পেতে হবে:

1 Tim  1 Tim

অভ্যন্তরীণ যোগদানগুলিতে কোনও দিক থাকে না (যেমন বাম বা ডান মতো) কারণ তারা সুস্পষ্টভাবে দ্বি নির্দেশমূলক - আমাদের উভয় পক্ষের ম্যাচ প্রয়োজন।

বাইরের যোগদান

অন্যদিকে, বাইরের সাথে যোগ দেয় এমন রেকর্ডগুলি সন্ধানের জন্য যা অন্য টেবিলে ম্যাচ নাও থাকতে পারে finding যেমন, আপনাকে কোন দিকটি নির্দিষ্ট করতে হবে এর যোগদান একটি অনুপস্থিত রেকর্ড অনুমোদিত হয়।

LEFT JOINএবং RIGHT JOINজন্য সাধারণভাবে সংক্ষেপে হয় LEFT OUTER JOINএবংRIGHT OUTER JOIN ; আমি নীচে তাদের পুরো নামগুলি ব্যবহার করব অভ্যন্তরীণ যোগগুলিতে বনাম যোগদানের ধারণাটিকে শক্তিশালী করতে।

বাম বাইরের যোগদান

একটি বাম বাহ্যিক জোড়, এর মতো:

SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;

... ডান টেবিলের সাথে ম্যাচ আছে কিনা তা নির্বিশেষে আমাদের বাম টেবিল থেকে সমস্ত রেকর্ড পেতে হবে:

1 Tim   1    Tim
2 Marta NULL NULL

রাইট আউটার জয়েন করুন

ডান বাহ্যিক যোগদান, এর মতো:

SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;

... বাম টেবিলে তাদের ম্যাচ আছে কি না তা নির্বিশেষে আমাদের ডান টেবিল থেকে সমস্ত রেকর্ড পেতে হবে:

1    Tim   1  Tim
NULL NULL  3  Katarina

সম্পূর্ণ আউটার জয়েন

একটি সম্পূর্ণ বাহ্যিক যোগদান আমাদের উভয় টেবিল থেকে সমস্ত রেকর্ড দেবে, অন্য টেবিলে তাদের ম্যাচ আছে কি না, উভয় পক্ষের যেখানে NUL আছে সেখানে মিল নেই। ফলাফলটি দেখতে এই রকম হবে:

1    Tim   1    Tim
2    Marta NULL NULL
NULL NULL  3    Katarina

তবে পাবলো সান্তা ক্রুজ যেমন উল্লেখ করেছেন, মাইএসকিউএল এটি সমর্থন করে না। আমরা এটির মতো বাম জোড় এবং ডান জোড়ার একটি ইউনিয়ন করে অনুকরণ করতে পারি:

SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`

UNION

SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;

আপনি এর UNIONঅর্থ হিসাবে ভাবতে পারেন "এই উভয় কোয়েরি চালান, তারপরে ফলাফল একে অপরের উপরে রেখে দিন"; সারিগুলির কিছু প্রথম কোয়েরি থেকে এবং কিছু দ্বিতীয় থেকে আসবে।

এটি লক্ষ করা উচিত যে UNIONমাইএসকিউএল-এ একটি হুবহু ডুপ্লিকেটগুলি মুছে ফেলবে: টিম এখানে উভয় প্রশ্নের মধ্যে উপস্থিত হবে, তবে কেবলমাত্র ফলাফলের ফলাফল UNIONতাকে একবারে তালিকাভুক্ত করে। আমার ডাটাবেস গুরু সহকর্মী মনে করেন যে এই আচরণের উপর নির্ভর করা উচিত নয়। সুতরাং এটি সম্পর্কে আরও স্পষ্ট করে বলতে, আমরা WHEREদ্বিতীয় ক্যোয়ারিতে একটি ধারা যুক্ত করতে পারি :

SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`

UNION

SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`
WHERE `t1`.`id` IS NULL;

অন্যদিকে, আপনি যদি কোনও কারণে সদৃশ দেখতে চান তবে আপনি ব্যবহার করতে পারেন UNION ALL


12
এই উত্তরটি এক বছরেরও বেশি পুরনো তবে এটি প্রমাণিত হয়েছে যে ২০০
নাথান লং

4
মাইএসকিউএল-এর জন্য আপনি আসলে ওভারল্যাপ না থাকলে ইউনিয়ন সমস্তের পরিবর্তে ইউনিয়ন ব্যবহার করা এড়াতে চান (উপরে পাভলের মন্তব্য দেখুন)। আপনি যদি এখানে আপনার উত্তরে সেই প্রভাবটিতে আরও কিছু তথ্য যুক্ত করতে পারেন, তবে আমার মনে হয় এটি আরও বিশদ হওয়ায় এটি এই প্রশ্নের পছন্দের উত্তর হতে চাই।
গ্যারেন

2
"ডাটাবেস গুরু সহকর্মী" থেকে দেওয়া পরামর্শটি সঠিক। রিলেশনাল মডেলের (টেড কোডড এবং ক্রিস ডেট দ্বারা সম্পন্ন সমস্ত তাত্ত্বিক কাজ) এর পরিপ্রেক্ষিতে, শেষ ফর্মের একটি কোয়েরি একটি সম্পূর্ণ আউটর জিনকে অনুকরণ করে, কারণ এটি দুটি স্বতন্ত্র সেটকে সংযুক্ত করে, দ্বিতীয় ক্যোয়ারী "নকল" প্রবর্তন করে না ( সারিগুলি ইতিমধ্যে প্রথম ক্যোয়ারী দ্বারা ফিরে এসেছে) যা এ দ্বারা উত্পাদিত হবে না FULL OUTER JOIN। সেভাবে প্রশ্ন করা, এবং সেই সদৃশগুলি সরানোর জন্য ইউএনআইএন ব্যবহার করে কোনও সমস্যা নেই। তবে সত্যিকারের FULL OUTER JOINএকটির প্রতিলিপি তৈরি করতে আমাদের বিরোধী-যুক্ত হওয়ার জন্য একটি প্রশ্নের প্রয়োজন।
spencer7593

1
@ ইসতিয়াকআহমেড: লক্ষ্যটি হ'ল সম্পূর্ণ আউটয়ার জয়েন অপারেশন অনুকরণ করা। দ্বিতীয় ক্যোয়ারিতে আমাদের সেই শর্তটি দরকার তাই এটি কেবল সারিগুলিতে ফিরে আসে যার কোনও মিল নেই (একটি অ্যান্টি-জয়েন প্যাটার্ন))। এই শর্ত ছাড়াই, ক্যোয়ারীটি একটি বাহ্যিক যোগদান ... এটি সারিগুলি যে ম্যাচগুলি এবং কোনও মিল না করেও ফিরে আসে। এবং যে সারিগুলি মেলে তা প্রথম প্রশ্নের মাধ্যমে ইতিমধ্যে ফিরে এসেছিল returned যদি দ্বিতীয় ক্যোয়ারী সেই একই সারিগুলি (আবার) ফেরত দেয় তবে আমরা সারিগুলি সদৃশ করেছি এবং আমাদের ফলাফল একটি সম্পূর্ণ আউট জয়েনের সমতুল্য হবে না
spencer7593

1
@ ইসতিয়াক আহমেদ: সত্য যে কোনও UNIONঅভিযান সেই নকলগুলি সরিয়ে ফেলবে; তবে এটি ডুপ্লিকেট সারি সহ সমস্ত সদৃশ সারিগুলিও সরিয়ে দেয় যা সম্পূর্ণ আউটয়ার জয়েন দ্বারা ফিরিয়ে দেওয়া হবে। অনুকরণ করতে a FULL JOIN b, সঠিক প্যাটার্নটি হ'ল (a LEFT JOIN b) UNION ALL (b ANTI JOIN a)
spencer7593

35

একটি unionকোয়েরি ব্যবহার করে সদৃশগুলি মুছে ফেলা হবে, এবং এটি এর আচরণের থেকে আলাদা full outer joinযা কখনই কোনও সদৃশ সরিয়ে দেয় না:

[Table: t1]                            [Table: t2]
value                                  value
-------                                -------
1                                      1
2                                      2
4                                      2
4                                      5

এটির প্রত্যাশিত ফলাফল full outer join:

value | value
------+-------
1     | 1
2     | 2
2     | 2
Null  | 5
4     | Null
4     | Null

এই ব্যবহারের ফল leftএবং right Joinসঙ্গে union:

value | value
------+-------
Null  | 5 
1     | 1
2     | 2
4     | Null

[SQL Fiddle]

আমার প্রস্তাবিত ক্যোয়ারী হ'ল:

select 
    t1.value, t2.value
from t1 
left outer join t2  
  on t1.value = t2.value
union all      -- Using `union all` instead of `union`
select 
    t1.value, t2.value
from t2 
left outer join t1 
  on t1.value = t2.value
where 
    t1.value IS NULL 

উপরের ক্যোয়ারির ফলাফল যা প্রত্যাশিত ফলাফল হিসাবে একই:

value | value
------+-------
1     | 1
2     | 2
2     | 2
4     | NULL
4     | NULL
NULL  | 5

[SQL Fiddle]


@ স্টিভ চেম্বারস : [অনেক ধন্যবাদ সহ মন্তব্য থেকে!]
দ্রষ্টব্য: দক্ষতার জন্য এবং এ হিসাবে একই ফলাফল উত্পন্ন করার জন্য এটি উভয়ই সেরা সমাধান হতে পারে FULL OUTER JOINএই ব্লগ পোস্টটি এটিকে আরও ভালভাবে ব্যাখ্যা করেছে - পদ্ধতি 2 থেকে উদ্ধৃতি দিতে: "এটি সদৃশ সারিগুলি সঠিকভাবে পরিচালনা করে এবং যা করা উচিত নয় তা অন্তর্ভুক্ত করে না UNION ALLplain প্লেইনের পরিবর্তে এটি ব্যবহার করা দরকার UNIONযা আমার রাখা নকলগুলি মুছে ফেলবে This এটি বড় ফলাফলের সেটগুলিতে উল্লেখযোগ্যভাবে আরও দক্ষ হতে পারে, যেহেতু নকলকে বাছাই এবং মুছে ফেলার দরকার নেই। "


আমি আরও একটি সমাধান যোগ করার সিদ্ধান্ত নিয়েছি যা full outer joinভিজ্যুয়ালাইজেশন এবং গণিত থেকে আসে , এটি উপরের চেয়ে ভাল নয় তবে আরও পাঠযোগ্য:

ফুল বাইরের মানে যোগদানের (t1 ∪ t2)সমস্ত: t1বা t2
(t1 ∪ t2) = (t1 ∩ t2) + t1_only + t2_onlyউভয় সমস্ত: t1এবং t2প্লাস সমস্ত t1যে নেই t2এবং প্লাস সব t2যে নেই t1:

-- (t1 ∩ t2): all in both t1 and t2
select t1.value, t2.value
from t1 join t2 on t1.value = t2.value    
union all  -- And plus 
-- all in t1 that not exists in t2
select t1.value, null
from t1
where not exists( select 1 from t2 where t2.value = t1.value)    
union all  -- and plus
-- all in t2 that not exists in t1
select null, t2.value
from t2
where not exists( select 1 from t1 where t2.value = t1.value)

[SQL Fiddle]


আমরা দু'বার একই টাস্কটি করছি, যদি টি 1 এবং টি 2 এর জন্য সাব কোয়েরি থাকে তবে মাইএসকিএল আরও একবার একই টাস্ক করতে হবে, তাই না? আমরা কি এই পরিস্থিতিতে ওরফে ব্যবহার করে এটি মুছে ফেলতে পারি
কবির হোসেন

আমি আপনাকে কিছু অস্থায়ী সারণী ব্যবহার করার পরামর্শ দিচ্ছি;)।
shA.t

5
দক্ষতা এবং এ হিসাবে একই ফলাফল উত্পন্ন করার জন্য এই পদ্ধতিটি সর্বোত্তম সমাধান বলে মনে হচ্ছে FULL OUTER JOINএই ব্লগ পোস্টটি এটিকে আরও ভালভাবে ব্যাখ্যা করেছে - পদ্ধতি 2 থেকে উদ্ধৃতি দেওয়ার জন্য: "এটি সদৃশ সারিগুলি সঠিকভাবে পরিচালনা করে এবং যা করা উচিত নয় তা অন্তর্ভুক্ত করে না plain প্লেইন ইউনিয়নের পরিবর্তে ইউনিয়ন সবগুলি ব্যবহার করা দরকার, যা আমি নকলগুলি অপসারণ করতে চাই রাখুন। বৃহত ফলাফলের সেটগুলিতে এটি উল্লেখযোগ্যভাবে আরও দক্ষ হতে পারে, যেহেতু নকলকে বাছাই এবং মুছে ফেলার দরকার নেই। "
স্টিভ চেম্বারস

2
@ স্টেভ চেম্বারস এটি অনেক দেরী করেছে, তবে আপনার মন্তব্যের জন্য ধন্যবাদ। আমি আপনার মন্তব্যটি যুক্ত করেছি তারপরে আরও হাইলাইট করার জবাব, আপনি যদি রাজি না হন তবে দয়া করে এটি আবার রোল করুন;)।
shA.t

কোনও সমস্যা নেই @ shA.t - আইএমওতে এটিতে আরও বেশি উত্স হওয়া উচিত এবং / অথবা স্বীকৃত উত্তর হওয়া উচিত।
স্টিভ চেম্বারস

6

মাইএসকিউএল-এ ফুল-আউটার-যোগ সিনট্যাক্স নেই। আপনাকে নিম্নে বাম যোগ এবং ডান যোগ দিতে উভয়ই অনুকরণ করতে হবে-

SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id  
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id

তবে মাইএসকিএল-তেও একটি রাইট জয়েন্ট সিনট্যাক্স নেই। মাইএসকিউএল এর মতে বাইরের সরলীকরণ যোগদান , ডান যোগদানের সমতুল্য বাম রূপান্তরিত হয় T1 এবং T2 সুইচিং দ্বারা যোগদানের FROMএবং ONক্যোয়ারীতে দফা। সুতরাং, মাইএসকিএল ক্যোয়ারী অপ্টিমাইজার মূল প্রশ্নটি নিম্নলিখিতটিতে অনুবাদ করে -

SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id  
UNION
SELECT * FROM t2
LEFT JOIN t1 ON t2.id = t1.id

এখন, মূল কোয়েরিটি যেমন আছে তেমন লেখার কোনও ক্ষতি নেই, তবে বলুন যে আপনার কাছে WHERE ধারাটির মতো ভবিষ্যদ্বাণী রয়েছে, যা পূর্বে যোগদানের পূর্বে বা একটি শৃঙ্খলে একটি ভবিষ্যদ্বাণীী ON, যা একটি সময়কালীন যোগদান পূর্বাভাস হয়, তবে আপনি শয়তানকে একবার দেখে নিতে চাইবে; যা বিস্তারিত আছে।

মাইএসকিউএল ক্যোয়ারী অপ্টিমাইজার নিয়মিতভাবে পূর্বাভাসগুলি পরীক্ষা করে যদি সেগুলি বাতিল হয়নাল-প্রত্যাখ্যাত সংজ্ঞা এবং উদাহরণ এখন, যদি আপনি সঠিক যোগদান করেন তবে টি 1 থেকে কলামটিতে পূর্বাভাস দিয়েছিলেন, তবে আপনি নাল-প্রত্যাখ্যাত পরিস্থিতিতে দৌড়ানোর ঝুঁকিতে পড়তে পারেন ।

উদাহরণস্বরূপ, আপনার নিম্নলিখিত কোয়েরি -

SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
WHERE t1.col1 = 'someValue'
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id
WHERE t1.col1 = 'someValue'

ক্যোরি অপটিমাইজার- এর দ্বারা নিম্নলিখিতটিতে অনুবাদ হয়ে যায় -

SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
WHERE t1.col1 = 'someValue'
UNION
SELECT * FROM t2
LEFT JOIN t1 ON t2.id = t1.id
WHERE t1.col1 = 'someValue'

সুতরাং সারণির ক্রম পরিবর্তন হয়েছে, তবে প্রিডিকেটটি এখনও টি 1 এ প্রয়োগ করা হয়েছে, তবে টি 1 এখন 'অন' ধারাটিতে রয়েছে। যদি t1.col1 NOT NULL কলাম হিসাবে সংজ্ঞায়িত করা হয় , তবে এই কোয়েরিটি বাতিল-প্রত্যাখ্যাত হবে

যে কোনও বাহ্যিক-যোগ (বাম, ডান, পূর্ণ) নাল-প্রত্যাখ্যাত তা মাই এসকিএল দ্বারা অভ্যন্তরীণ-যোগে রূপান্তরিত হয়।

সুতরাং আপনি যে ফলাফলগুলির প্রত্যাশা করছেন তা মাইএসকিএল থেকে ফিরে আসা থেকে সম্পূর্ণ আলাদা হতে পারে। আপনি এটি মাইএসকিএল রাইটস জোনে একটি ত্রুটি মনে করতে পারেন, তবে এটি ঠিক নয়। এটি ঠিক কিভাবে MySQL ক্যোয়ারী-অপ্টিমাইজার কাজ করে। সুতরাং বিকাশকারী ইনচার্জ যখন তিনি কোয়েরিটি তৈরি করছেন তখন এই সংক্ষিপ্তসারগুলিতে মনোযোগ দিতে হবে।


4

এসকিউএলাইটে আপনার এটি করা উচিত:

SELECT * 
FROM leftTable lt 
LEFT JOIN rightTable rt ON lt.id = rt.lrid 
UNION
SELECT lt.*, rl.*  -- To match column set
FROM rightTable rt 
LEFT JOIN  leftTable lt ON lt.id = rt.lrid

আমরা কি এটি ব্যবহার করতে পারি? যেমন: নির্বাচন করুন * বামে থেকে টেবিল এলটি বামে যোগ দিন ডান টেবিল আরটি এলটি.আইডি = আরটি.ল্রিড ইউনিয়ন নির্বাচন করুন লে।।, আরএল। ;
কবির হোসেন

হ্যাঁ তবে
এসকিউএলাইট

4

উপরের উত্তরগুলির মধ্যে কোনটিই প্রকৃতপক্ষে সঠিক নয়, কারণ সদৃশ মান রয়েছে যখন তারা শব্দার্থবিজ্ঞান অনুসরণ করে না।

(এই সদৃশ থেকে ) যেমন একটি প্রশ্নের জন্য :

SELECT * FROM t1 FULL OUTER JOIN t2 ON t1.Name = t2.Name;

সঠিক সমতুল্য হ'ল:

SELECT t1.*, t2.*
FROM (SELECT name FROM t1 UNION  -- This is intentionally UNION to remove duplicates
      SELECT name FROM t2
     ) n LEFT JOIN
     t1
     ON t1.name = n.name LEFT JOIN
     t2
     ON t2.name = n.name;

NULLমানগুলির সাথে কাজ করার জন্য আপনার যদি NULLএটির প্রয়োজন হয় (যা প্রয়োজনীয়ও হতে পারে), তবে- তুলনায় <=>অপেক্ষাকৃত নিরাপদ তুলনা অপারেটরটি ব্যবহার করুন =


3
এটি প্রায়শই একটি ভাল সমাধান, তবে কলামটি শূন্য FULL OUTER JOINহলে এটি তার চেয়ে আলাদা ফলাফল দিতে পারে nameunion allবিরোধী-যোগ প্যাটার্ন সঙ্গে ক্যোয়ারী বাইরের সঠিকভাবে আচরণ যোগদানের নকল করা উচিত, কিন্তু যা সমাধান আরো উপযুক্ত প্রসঙ্গ এবং সীমাবদ্ধতার যে টেবিল সক্রিয় উপর নির্ভর করে।
fthiella

@fthiella । । এটি একটি ভাল পয়েন্ট। আমি উত্তর সামঞ্জস্য।
গর্ডন লিনোফ

1
ঠিক আছে, তবে নাল-সেফ তুলনা অপারেটরটি এই জয়েনটিকে সফল করে তুলবে, যা আপনার টি
-১

@fthiella । । এটি করার সর্বোত্তম উপায় সম্পর্কে আমাকে ভাবতে হবে। তবে গৃহীত উত্তরটি কতটা ভুল, তা প্রদত্ত প্রায় কোনও কিছুই সঠিক উত্তরের কাছাকাছি। (
দু'দিকে

1
হ্যাঁ গৃহীত উত্তরটি ভুল, সাধারণ সমাধান হিসাবে আমি মনে করি এটি ব্যবহার করা সঠিক union all, তবে সেই উত্তরটি প্রথম বা দ্বিতীয় কোয়েরিতে একটি অ্যান্টি-জয়েন প্যাটার্ন মিস করে যা বিদ্যমান নকলগুলি রাখে তবে নতুন উত্তর যুক্ত হওয়া থেকে বাধা দেয়। প্রসঙ্গের উপর নির্ভর করে অন্যান্য সমাধানগুলি (এটির মতো) আরও উপযুক্ত হতে পারে।
fthiella

3

আরও স্পষ্টতার জন্য shA.t এর প্রশ্নের পরিবর্তিত হয়েছে:

-- t1 left join t2
SELECT t1.value, t2.value
FROM t1 LEFT JOIN t2 ON t1.value = t2.value   

    UNION ALL -- include duplicates

-- t1 right exclude join t2 (records found only in t2)
SELECT t1.value, t2.value
FROM t1 RIGHT JOIN t2 ON t1.value = t2.value
WHERE t2.value IS NULL 

3

আপনি নিম্নলিখিতটি করতে পারেন:

(SELECT 
    *
FROM
    table1 t1
        LEFT JOIN
    table2 t2 ON t1.id = t2.id
WHERE
    t2.id IS NULL)
UNION ALL
 (SELECT 
    *
FROM
    table1 t1
        RIGHT JOIN
    table2 t2 ON t1.id = t2.id
WHERE
    t1.id IS NULL);

1

ক্রস যোগদানের সমাধান সম্পর্কে আপনি কী বলবেন ?

SELECT t1.*, t2.*
FROM table1 t1
INNER JOIN table2 t2 
ON 1=1;

2
না, এটি ক্রস জয়েন। এটি টি-তে প্রতিটি সারি টি -2-তে প্রতিটি সারির সাথে মিলবে, select (select count(*) from t1) * (select count(*) from t2))ফলাফল সেটটিতে সারি সহ সমস্ত সম্ভাব্য সংমিশ্রণের সেট উপস্থাপন করবে।
মার্ক এল।

যদিও এই কোডটি প্রশ্নের উত্তর দিতে পারে, কীভাবে এবং কেন এটি সমস্যার সমাধান করে তা সম্পর্কিত অতিরিক্ত প্রসঙ্গ সরবরাহ করলে উত্তরের দীর্ঘমেয়াদী মান উন্নত হবে।
আলেকজান্ডার

কোন সংযোজন সহায়ক হতে পারে? উদাহরণস্বরূপ?
সুপার মারিও


0

এটিও সম্ভব, তবে আপনাকে নির্বাচনের ক্ষেত্রে একই ক্ষেত্রের নাম উল্লেখ করতে হবে।

SELECT t1.name, t2.name FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT t1.name, t2.name FROM t2
LEFT JOIN t1 ON t1.id = t2.id

এটি কেবল বাম জোড়ায় ফলাফলগুলি অনুলিপি করছে।
ম্যাথু

-1

আমি প্রতিক্রিয়াটি স্থির করেছি, এবং কার্যগুলিতে সমস্ত সারি অন্তর্ভুক্ত রয়েছে (পাভেল লিকের প্রতিক্রিয়ার ভিত্তিতে)

    (
    SELECT a.* FROM tablea a
    LEFT JOIN tableb b ON a.`key` = b.key
    WHERE b.`key` is null
    )
    UNION ALL
    (
    SELECT a.* FROM tablea a
    LEFT JOIN tableb b ON a.`key` = b.key
    where  a.`key` = b.`key`
    )
    UNION ALL
    (
    SELECT b.* FROM tablea a
    right JOIN tableb b ON b.`key` = a.key
    WHERE a.`key` is null
    );

না, এটি "বাহ্যিক-কেবল" যোগদানের এক প্রকার, এটি কেবলমাত্র সারিগুলি ফিরিয়ে দেবে tableaযা থেকে কোনও মিল নেই tablebএবং বিপরীতে। আপনি চেষ্টা করেছেন UNION ALL, যা কেবল তখনই কার্যকর হবে যদি এই দুটি টেবিল সমানভাবে কলামগুলি অর্ডার করে, যা গ্যারান্টিযুক্ত নয়।
মার্ক এল।

এটি কাজ করে, আমি অস্থায়ী ডাটাবেস টেবিল (1,2,3,4,5,6) এবং টেবিল (4,5,6,7,8,9) তৈরি করি এর সারিগুলিতে 3 টি "আইডি", "নম্বর" এবং পাঠ্য হিসাবে "নাম_নম্বার", এবং এর ফলস্বরূপ কেবলমাত্র (1,2,3,7,8,9) কাজ করে
রুজ

1
এটি বাইরের যোগদান নয় not বাইরের যোগদানের সাথে মিলে যাওয়া সদস্যগুলিও অন্তর্ভুক্ত থাকে।
মার্ক এল।

এই নতুন বাক্যে সমস্ত ফলাফল রয়েছে 1,2, ..., 9
রুবান রুজ

-2

উত্তর:

SELECT * FROM t1 FULL OUTER JOIN t2 ON t1.id = t2.id;

নিম্নলিখিত হিসাবে পুনরায় তৈরি করা যেতে পারে:

 SELECT t1.*, t2.* 
 FROM (SELECT * FROM t1 UNION SELECT name FROM t2) tmp
 LEFT JOIN t1 ON t1.id = tmp.id
 LEFT JOIN t2 ON t2.id = tmp.id;

একটি ইউনিয়ন বা ইউনিয়ন সমস্ত উত্তর ব্যবহার করে বেস টেবিলগুলির নকল এন্ট্রি রয়েছে এমন প্রান্তের মামলাটি কভার করে না।

ব্যাখ্যা:

একটি প্রান্তের কেস রয়েছে যেটি একটি ইউনিয়ন বা ইউনিয়ন সব কভার করতে পারে না। আমরা এটি মাইএসকিএলে পরীক্ষা করতে পারি না কারণ এটি সম্পূর্ণ আউট জয়েনগুলিকে সমর্থন করে না, তবে আমরা এটি একটি ডাটাবেসে চিত্রিত করতে পারি যা এটি সমর্থন করে:

 WITH cte_t1 AS
 (
       SELECT 1 AS id1
       UNION ALL SELECT 2
       UNION ALL SELECT 5
       UNION ALL SELECT 6
       UNION ALL SELECT 6
 ),
cte_t2 AS
(
      SELECT 3 AS id2
      UNION ALL SELECT 4
      UNION ALL SELECT 5
      UNION ALL SELECT 6
      UNION ALL SELECT 6
)
SELECT  *  FROM  cte_t1 t1 FULL OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2;

This gives us this answer:

id1  id2
1  NULL
2  NULL
NULL  3
NULL  4
5  5
6  6
6  6
6  6
6  6

ইউনিয়ন সমাধান:

SELECT  * FROM  cte_t1 t1 LEFT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2
UNION    
SELECT  * FROM cte_t1 t1 RIGHT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2

একটি ভুল উত্তর দেয়:

 id1  id2
NULL  3
NULL  4
1  NULL
2  NULL
5  5
6  6

ইউনিয়ন সব সমাধান:

SELECT  * FROM cte_t1 t1 LEFT OUTER join cte_t2 t2 ON t1.id1 = t2.id2
UNION ALL
SELECT  * FROM  cte_t1 t1 RIGHT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2

ভুলও।

id1  id2
1  NULL
2  NULL
5  5
6  6
6  6
6  6
6  6
NULL  3
NULL  4
5  5
6  6
6  6
6  6
6  6

যেখানে এই ক্যোয়ারী:

SELECT t1.*, t2.*
FROM (SELECT * FROM t1 UNION SELECT name FROM t2) tmp 
LEFT JOIN t1 ON t1.id = tmp.id 
LEFT JOIN t2 ON t2.id = tmp.id;

নিম্নলিখিত দেয়:

id1  id2
1  NULL
2  NULL
NULL  3
NULL  4
5  5
6  6
6  6
6  6
6  6

ক্রমটি আলাদা, তবে অন্যথায় সঠিক উত্তরটির সাথে মেলে।


এটি দুর্দান্ত, তবে UNION ALLসমাধানটির ভুল ব্যাখ্যা দেয় । এছাড়াও, এটি একটি সমাধান ব্যবহার করে উপস্থাপন করে UNIONযা বৃহত উত্সের টেবিলগুলিতে ধীর গতিতে হবে কারণ প্রয়োজনীয় ডি-নকলের কারণে। অবশেষে, এটি সংকলন করবে না, কারণ ক্ষেত্রটি idসাবকোয়ারিতে নেই tmp
মার্ক এল।

আমি কখনই গতি সম্পর্কে দাবি জানায়নি, এবং ওপিও গতি সম্পর্কে কোনও উল্লেখ করেনি। ইউনিয়ন সমস্তকে ধরে নিয়ে (আপনি কোনটির উপর নির্ভর করেন না) এবং এটি উভয়ই সঠিক উত্তর দেয়, আমরা যদি দ্রুততর যে একটি দৃtion়ভাবে দাবি করতে চাইতাম, আমাদের বেঞ্চমার্ক সরবরাহ করতে হবে, এবং এটি ওপি থেকে বিস্তৃত হবে প্রশ্ন।
অ্যাঞ্জেলস

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

3
ভুল উপস্থাপনা: " UNION ALLসমাধান: ... এটিও ভুল।" আপনি যে কোডটি উপস্থাপন করেছেন তা ডান-যোগ ( where t1.id1 is null) থেকে অন্তর্ভুক্ত-বর্জনকে ছেড়ে দেয় যা অবশ্যই সরবরাহ করা উচিত UNION ALL। যার অর্থ হল, আপনার সমাধানটি অন্য সকলকে ট্রাম্প করে, কেবল তখনই যখন এইগুলি সমাধানগুলির মধ্যে একটির ভুলভাবে প্রয়োগ করা হয়। "নমনীয়তা" তে, পয়েন্টটি নেওয়া হয়েছে। এটা ছিল কৃতজ্ঞ, আমার ক্ষমা।
মার্ক এল।

-3

এসকিউএল স্ট্যান্ডার্ডটি বলছে full join onযে inner join onসারিগুলি union allতুলনাহীন বাম টেবিলের সারিগুলি নাল দ্বারা প্রসারিত union allডান টেবিল সারিগুলি নাল দ্বারা প্রসারিত। অর্থাৎ inner join onসারি union allসারিগুলিতে left join onকিন্তু inner join on union allসারিগুলিতে right join onনয় তবে নেই inner join on

অর্থাত left join onসারি union all right join onসারি নেই inner join on। অথবা আপনি যদি জানেন তাঁরা আপনার inner join onফলাফলের "তাহলে একটি নির্দিষ্ট ডানদিকের সারণী কলামে নাল থাকতে পারে না right join onনেই সারি inner join on" সারি হয় right join onসঙ্গে onশর্ত দ্বারা বর্ধিত andকলামের is null

অর্থাৎ একইভাবে right join on union allউপযুক্ত left join onসারি।

থেকে মধ্যবর্তী "ভিতরের JOIN" এবং "বহিঃস্থ সংযোগ" পার্থক্য কি? :

(এসকিউএল স্ট্যান্ডার্ড 2006 এসকিউএল / ফাউন্ডেশন 7.7 সিন্ট্যাক্স বিধি 1, সাধারণ বিধি 1 বি, 3 সি ও ডি, 5 খ।)

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