यह एक बहुत अच्छा सवाल है, इसलिए मैंने अपने ब्लॉग पर इस विषय के बारे में एक बहुत विस्तृत लेख लिखने का फैसला किया है ।
डेटाबेस तालिका मॉडल
मान लेते हैं कि हमारे डेटाबेस में निम्नलिखित दो टेबल हैं, जो एक-से-कई टेबल संबंध बनाते हैं।
student
तालिका अभिभावक होता है औरstudent_grade
बच्चे को मेज है, क्योंकि यह एक student_id विदेशी कुंजी स्तंभ छात्र तालिका में आईडी प्राथमिक कुंजी स्तंभ को संदर्भित है।
student table
निम्नलिखित दो रिकॉर्ड में शामिल हैं:
| id | first_name | last_name | admission_score |
|----|------------|-----------|-----------------|
| 1 | Alice | Smith | 8.95 |
| 2 | Bob | Johnson | 8.75 |
और, student_grade
तालिका उन ग्रेडों को संग्रहीत करती है जो छात्र प्राप्त करते हैं:
| id | class_name | grade | student_id |
|----|------------|-------|------------|
| 1 | Math | 10 | 1 |
| 2 | Math | 9.5 | 1 |
| 3 | Math | 9.75 | 1 |
| 4 | Science | 9.5 | 1 |
| 5 | Science | 9 | 1 |
| 6 | Science | 9.25 | 1 |
| 7 | Math | 8.5 | 2 |
| 8 | Math | 9.5 | 2 |
| 9 | Math | 9 | 2 |
| 10 | Science | 10 | 2 |
| 11 | Science | 9.4 | 2 |
SQL EXISTS
मान लीजिए कि हम उन सभी छात्रों को प्राप्त करना चाहते हैं जिन्हें गणित कक्षा में 10 ग्रेड प्राप्त हुए हैं।
यदि हम केवल छात्र पहचानकर्ता में रुचि रखते हैं, तो हम इस तरह एक क्वेरी चला सकते हैं:
SELECT
student_grade.student_id
FROM
student_grade
WHERE
student_grade.grade = 10 AND
student_grade.class_name = 'Math'
ORDER BY
student_grade.student_id
लेकिन, आवेदन student
केवल पहचानकर्ता का पूरा नाम प्रदर्शित करने में रुचि रखता है , इसलिए हमें इसकी जानकारी चाहिएstudent
तालिका ।
student
गणित में 10 ग्रेड वाले रिकॉर्ड को फ़िल्टर करने के लिए , हम इस तरह से EXISTS SQL ऑपरेटर का उपयोग कर सकते हैं:
SELECT
id, first_name, last_name
FROM
student
WHERE EXISTS (
SELECT 1
FROM
student_grade
WHERE
student_grade.student_id = student.id AND
student_grade.grade = 10 AND
student_grade.class_name = 'Math'
)
ORDER BY id
ऊपर क्वेरी चलाते समय, हम देख सकते हैं कि केवल ऐलिस पंक्ति चयनित है:
| id | first_name | last_name |
|----|------------|-----------|
| 1 | Alice | Smith |
बाहरी क्वेरी उस student
पंक्ति कॉलम का चयन करती है जिसे हम ग्राहक को वापस करने में रुचि रखते हैं। हालाँकि, WHERE क्लॉज संबंधित आंतरिक उपकुंजी के साथ EXISTS ऑपरेटर का उपयोग कर रहा है।
यदि किसी पंक्ति का चयन नहीं किया जाता है, तो उप-परिचालक कम से कम एक रिकॉर्ड और गलत रिटर्न देता है, तो सही है। डेटाबेस इंजन को पूरी तरह से उपकुंजी चलाने की आवश्यकता नहीं है। यदि एक एकल रिकॉर्ड का मिलान किया जाता है, तो EXISTS ऑपरेटर सही हो जाता है, और संबंधित अन्य क्वेरी पंक्ति चयनित होती है।
इनर सबक्वेरी को सहसंबंधित किया जाता है क्योंकि छात्र_एड कॉलम student_grade
तालिका id कॉलम को बाहरी छात्र तालिका के आईडी कॉलम से मिलान किया जाता है।
SQL EXISTS नहीं है
आइए विचार करें कि हम उन सभी छात्रों का चयन करना चाहते हैं जिनके पास ग्रेड 9 से कम नहीं है। इसके लिए हम NOT EXISTS का उपयोग कर सकते हैं, जो EXISTS ऑपरेटर के तर्क को नकारता है।
इसलिए, अंतर्निहित सबस्क्रिप्शन कोई रिकॉर्ड नहीं है, तो नहीं EXISTS ऑपरेटर सही देता है। हालाँकि, यदि किसी एकल रिकॉर्ड को आंतरिक सबक्वेरी द्वारा मिलान किया जाता है, तो NOT EXISTS ऑपरेटर गलत नहीं लौटेगा, और सबक्वेरी निष्पादन को रोका जा सकता है।
उन सभी छात्र रिकॉर्ड्स से मिलान करने के लिए, जिनका 9 से कम मान वाला कोई संबद्ध छात्र_ग्रेड नहीं है, हम निम्नलिखित SQL क्वेरी चला सकते हैं:
SELECT
id, first_name, last_name
FROM
student
WHERE NOT EXISTS (
SELECT 1
FROM
student_grade
WHERE
student_grade.student_id = student.id AND
student_grade.grade < 9
)
ORDER BY id
ऊपर क्वेरी चलाते समय, हम देख सकते हैं कि केवल ऐलिस रिकॉर्ड का मिलान किया गया है:
| id | first_name | last_name |
|----|------------|-----------|
| 1 | Alice | Smith |
तो, SQL EXISTS और NOT EXISTS ऑपरेटरों का उपयोग करने का लाभ यह है कि जब तक एक मिलान रिकॉर्ड पाया जाता है तब तक आंतरिक सबक्वेरी निष्पादन को रोका जा सकता है।