Free tutorials & notes in Hindi & English · Clean code examples 🧰 मुफ़्त PDF और फ़ोटो टूल्स →
MySQL + SQL · Lesson 71

UNION से MySQL में FULL OUTER JOIN

FULL OUTER JOIN का असली मतलब

कल्पना कीजिए कागज़ पर दो lists हैं। एक students की, दूसरी classes की। FULL OUTER JOIN का मतलब है — आप बैठकर एक ऐसी combined शीट बनाते हैं जिसमें सब कुछ दिखे: हर वह student जो किसी class में बैठा है, वे students भी जिनकी अभी कोई class नहीं, और वे classes भी जिनमें अभी कोई student नहीं। कोई भी page से बाहर नहीं छूटता।

पूरी बात यही है। सामान्य (inner) join केवल matching rows दिखाता है — दोनों तरफ़ के बचे-खुचे लोग गायब हो जाते हैं। LEFT JOIN सारे students रखता है पर खाली classes छोड़ देता है। FULL OUTER JOIN किसी को नहीं छोड़ता: matched rows, left-only rows और right-only rows सब एक साथ आते हैं।

💡 एक-लाइन परिभाषा

FULL OUTER JOIN = सारे matches + left table की बिना match वाली rows + right table की बिना match वाली rows, सब एक ही result में।

MySQL में FULL OUTER JOIN क्यों नहीं है

यहीं लोग अटकते हैं: MySQL में FULL OUTER JOIN keyword है ही नहीं। PostgreSQL और SQL Server जैसे databases में यह है, पर MySQL ने कभी नहीं जोड़ा। लिखने पर MySQL सीधे error दे देता है।

MySQL
SELECT * FROM students
FULL OUTER JOIN classes
  ON students.class_id = classes.class_id;
Output:
ERROR 1064 (42000): You have an error in your SQL syntax near 'FULL OUTER JOIN classes ...'

तो एक keyword की जगह हम वही result दो हिस्सों से बनाते हैं जिन्हें MySQL समझता है: एक LEFT JOIN और एक UNION ALL। एक बार pattern समझ आ गया तो हर जगह आसानी से दोहरा सकते हैं।

हमारी sample tables

चलिए एक छोटा, भरोसेमंद उदाहरण लेते हैं ताकि output हाथ से जाँचना आसान हो। दो tables: students और classes।

MySQL
CREATE TABLE classes (
    class_id   INT PRIMARY KEY,
    class_name VARCHAR(30)
);

CREATE TABLE students (
    student_id   INT PRIMARY KEY,
    student_name VARCHAR(30),
    class_id     INT   -- assign न हो तो NULL
);

INSERT INTO classes VALUES
(10,'X-A'), (20,'X-B'), (30,'XI-A');

INSERT INTO students VALUES
(1,'Aarav',10),
(2,'Diya',20),
(3,'Kabir',10),
(4,'Meera',20),
(5,'Vihaan',NULL);   -- अभी किसी class में नहीं

Data ध्यान से पढ़िए, क्योंकि इसमें ठीक वही दो दिलचस्प cases हैं:

  • Vihaan एक student है जिसका class_id = NULL है — यह left-only row है (बिना class वाला student)।
  • XI-A (class 30) की तरफ़ कोई student इशारा नहीं करता — यह right-only row है (बिना student वाली class)।

सही full outer join को ये दोनों दिखाने ही होंगे, साथ में चार सामान्य matches भी। यानी हमें पहले से पता है कि answer में 6 rows होनी चाहिए। पहले row count का अंदाज़ा लगाना बाद में query जाँचने का सबसे आसान तरीका है।

LEFT JOIN + UNION ALL वाला तरीका

Recipe के दो हिस्से हैं। पहला हिस्सा हर student उठाता है (match हो या न हो)। दूसरा हिस्सा हर वह class उठाता है जो पीछे छूट गई, और केवल वही।

MySQL
-- हिस्सा 1: हर student, match होने पर class भी
SELECT s.student_id, s.student_name,
       c.class_id, c.class_name
FROM students AS s
LEFT JOIN classes AS c
       ON c.class_id = s.class_id

UNION ALL

-- हिस्सा 2: केवल वे classes जिनसे कोई student match नहीं हुआ
SELECT s.student_id, s.student_name,
       c.class_id, c.class_name
FROM classes AS c
LEFT JOIN students AS s
       ON s.class_id = c.class_id
WHERE s.student_id IS NULL;

जादू उस आख़िरी लाइन में है: WHERE s.student_id IS NULL। दूसरे हिस्से में हम classes से शुरू करते हैं और students जोड़ने की कोशिश करते हैं। जिस class को पहले ही कोई student मिल गया, उसे यह filter हटा देता है — क्योंकि वे matches हम पहले हिस्से में गिन चुके हैं। बचती हैं तो केवल अकेली classes (XI-A)। यही चीज़ rows को दो बार आने से रोकती है।

💡 student_id IS NULL ही क्यों, class_id क्यों नहीं?

हमेशा वह column जाँचिए जो सामान्य data में NULL हो ही नहीं सकता — यहाँ primary key student_id। match fail होने पर यही key खाली आती है, जो "match नहीं मिला" का भरोसेमंद संकेत है।

पूरा output समझें

Output:
student_id | student_name | class_id | class_name
1 | Aarav | 10 | X-A
2 | Diya | 20 | X-B
3 | Kabir | 10 | X-A
4 | Meera | 20 | X-B
5 | Vihaan | NULL | NULL
NULL | NULL | 30 | XI-A

आख़िरी दो rows देखिए — इन्हीं के लिए तो यह सब किया। Vihaan की class columns NULL हैं (बिना class वाला student)। XI-A की student columns NULL हैं (बिना student वाली class)। ऊपर की चार rows सामान्य matches हैं। कुल छह rows, ठीक जैसा हमने अंदाज़ा लगाया था।

UNION बनाम UNION ALL (कौन सा लें)

दोनों एक result को दूसरे के ऊपर जोड़ते हैं, पर एक अहम फ़र्क है।

बातUNIONUNION ALL
Duplicate rows हटाता है?हाँ (अपने आप)नहीं (सब रखता है)
गतिधीमा (extra sort/dedupe)तेज़
यहाँ सही विकल्प?ज़रूरत नहींहाँ

चूँकि हमारा WHERE ... IS NULL filter पहले ही पक्का कर देता है कि कोई row दोहरी नहीं होगी, UNION चलाना बस उन duplicates को ढूँढने में समय बर्बाद करेगा जो हो ही नहीं सकते। UNION ALL सही और तेज़ विकल्प है। सादा UNION तभी लें जब सच में duplicate rows की उम्मीद हो और उन्हें merge करना हो।

आम गलतियाँ

  • FULL OUTER JOIN लिखकर चलने की उम्मीद करना। MySQL इसे सीधे reject कर देगा। इसे चालू करने वाली कोई छिपी setting नहीं है — keyword है ही नहीं।
  • सादा UNION इस्तेमाल कर असली rows खो देना। अगर दो सचमुच अलग rows कुछ ही columns select करने पर एक जैसी दिखें, तो UNION उन्हें चुपचाप merge कर देता है और row count बदल जाता है।
  • WHERE ... IS NULL filter भूल जाना। इसके बिना पहले हिस्से वाले matched pairs उल्टे हिस्से में दोबारा जुड़ जाते हैं और matches दो बार दिखते हैं।
  • Primary key की जगह join key पर filter लगाना। अगर join column ख़ुद NULL हो सकता है, तो उसे NULL जाँचना ग़लत "no match" देगा। हमेशा जिस side को जाँच रहे हैं उसकी non-nullable primary key जाँचिए।
🏋️ अभ्यास

एक और class (40,'XI-B') जोड़िए जिसमें कोई student न हो, और एक और student (6,'Ishan',NULL)। कुछ चलाने से पहले नई row count कागज़ पर अनुमानित कीजिए, फिर full outer join query चलाकर मिलान कीजिए। (संकेत: दो नई unmatched rows यानी answer आठ हो जाएगा।)

सारांश

  • FULL OUTER JOIN सारे matches और दोनों tables की बची rows लौटाता है।
  • MySQL में FULL OUTER JOIN keyword नहीं — इसे ख़ुद बनाना पड़ता है।
  • Pattern है LEFT JOIN … UNION ALL … उल्टा LEFT JOIN साथ में WHERE key IS NULL।
  • UNION ALL लें (UNION नहीं) — filter पहले ही duplicates रोक देता है, तो यह तेज़ है।
  • पहले row count का अनुमान लगाइए; इससे query जाँचना बेहद आसान हो जाता है।

यह समझ आते ही बाकी joins आसान लगेंगे। आगे SELECT DISTINCT से duplicate values हटाना देखिए, या cross और self join lesson में basics दोहराइए।

अक्सर पूछे जाने वाले प्रश्न (FAQ)

क्या MySQL FULL OUTER JOIN support करता है?
नहीं। MySQL (MySQL 8.x तक भी) में FULL OUTER JOIN keyword मौजूद नहीं है। लिखने पर syntax error आता है। इसे LEFT JOIN और एक उल्टे LEFT JOIN को UNION ALL से जोड़कर बनाया जाता है।
MySQL में full outer join लिखने का सबसे आसान तरीका क्या है?
पहली table के लिए LEFT JOIN लिखें, फिर दूसरी table से शुरू होने वाला एक और LEFT JOIN UNION ALL से जोड़ें, जिसमें केवल unmatched rows रखें (WHERE key IS NULL से)। दोनों मिलकर matched rows और दोनों तरफ़ की unmatched rows देते हैं।
यहाँ UNION की जगह UNION ALL क्यों इस्तेमाल करते हैं?
दूसरी query का WHERE ... IS NULL filter matched rows को दोबारा आने से पहले ही रोक देता है, तो हटाने के लिए कुछ बचता ही नहीं। UNION ALL तेज़ है क्योंकि यह वह duplicate हटाने वाला step छोड़ देता है जो सादा UNION हमेशा चलाता है।
Matched rows को दो बार आने से कैसे रोकें?
दूसरी (उल्टी) query में पहली table की primary key IS NULL लगाएँ। इससे केवल right-only rows रहती हैं, और पहली query वाले matched pairs दोबारा नहीं जुड़ते।
क्या बिना UNION के full outer join मिल सकता है?
MySQL में साफ़-सुथरे तरीके से नहीं। कुछ लोग application code में दो अलग result sets के साथ जुगाड़ करते हैं, पर SQL के अंदर मानक और भरोसेमंद तरीका इसी page वाला LEFT JOIN + UNION ALL ही है।
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 लाइव कोड एडिटर

इस पेज के प्रोग्राम यहीं तैयार हैं — चलाएँ, बदलें और सीखें। कुछ भी इंस्टॉल किए बिना।
OneCompiler द्वारा संचालित। कोड एडिटर में अपने आप आ जाता है — Run दबाकर आउटपुट देखें। अगर एडिटर न खुले तो नए टैब में खोलें.
अगला topicNested Queries और Subqueries आपकी प्रगति: 71 / 151 (47%) · Lesson 72 / 151 आगे बढ़ें →

यह lesson कैसा लगा?

आपकी राय से हम content और बेहतर बनाते हैं।

अपना review और सुझाव लिखें (वैकल्पिक)

Review approve होने के बाद आपका नाम और शहर इसके साथ public दिख सकते हैं। Email या phone न लिखें।

▶ CodingEasily on YouTube

Video से सीखें – आसान Hindi में

चुनी हुई video: RDBMS भाग 3 – Class XI Commerce IT

▶ Channel subscribe करें