संरचित क्वेरी भाषा (SQL)

SQL वह भाषा है जिसे हर संबंधपरक डेटाबेस समझता है: एक कथन तालिका बनाता है, दूसरा उसे भरता है, और तीसरा उससे प्रश्न पूछता है। पाठ्यक्रम MySQL का प्रयोग करता है, एक निःशुल्क और ओपन-सोर्स संबंधपरक DBMS। यह अध्याय तालिका परिभाषित करने वाले डेटा प्रकारों व प्रतिबंधों को, तालिकाएँ बनाने, बदलने और हटाने वाले कथनों (DDL) को और पंक्तियाँ जोड़ने, बदलने और हटाने वाले कथनों (DML) को, और फिर पेपर के केंद्र — SELECT, उसके फ़िल्टरों, क्रमबद्धन, फ़ंक्शनों, समूहन और जॉइन सहित — को लेता है। अंत में यह बताता है कि पायथन प्रोग्राम MySQL से कैसे बात करता है। अधिकांश SQL प्रश्न एक तालिका देकर किसी क्वेरी का परिणाम पूछते हैं, अतः यहाँ का हर नियम नीचे दी STUDENT तालिका पर दिखाया गया है।

डेटा प्रकार और प्रतिबंध

सामान्य MySQL डेटा प्रकार
प्रकारक्या रखता है
CHAR(n)n वर्णों का निश्चित-लंबाई पाठ (0–255); छोटा मान n तक स्पेस से भरा जाता है
VARCHAR(n)अधिकतम n वर्णों का परिवर्ती-लंबाई पाठ; केवल वास्तविक लंबाई सहेजी जाती है
INTपूर्ण संख्याएँ (4 बाइट)
FLOATदशमलव बिंदु वाली संख्याएँ
DATE'YYYY-MM-DD' प्रारूप में तिथि
  • NOT NULL — हर पंक्ति में स्तंभ का मान होना चाहिए।
  • UNIQUE — किन्हीं दो पंक्तियों में स्तंभ का मान समान नहीं हो सकता।
  • DEFAULT — मान न दिए जाने पर प्रयुक्त मान।
  • PRIMARY KEY — हर पंक्ति की पहचान करता है: अद्वितीय और NOT NULL एक साथ।
  • FOREIGN KEY — मान संदर्भित तालिका की प्राथमिक कुंजी में मौजूद होने चाहिए।

DDL और DML कथन

SQL कथन दो परिवारों में आते हैं। डेटा परिभाषा भाषा (DDL) संरचना पर काम करती है: CREATE DATABASE, CREATE TABLE, ALTER TABLE (स्तंभ जोड़ने, हटाने या बदलने, या प्राथमिक या विदेशी कुंजी जोड़ने के लिए) और DROP TABLE / DROP DATABASE। डेटा परिचालन भाषा (DML) पंक्तियों पर काम करती है: INSERT INTO … VALUES …, UPDATE … SET … WHERE … और DELETE FROM … WHERE …। USE dbname डेटाबेस चुनता है, SHOW TABLES उसकी तालिकाएँ सूचीबद्ध करता है और DESCRIBE tablename (या DESC) तालिका की संरचना दिखाता है। कीवर्ड केस-संवेदी नहीं हैं, और हर कथन अर्धविराम पर समाप्त होता है।

उदाहरण के लिए, इस अध्याय में प्रयुक्त STUDENT तालिका इस प्रकार बनाई और उसमें एक पंक्ति जोड़ी जा सकती है:
CREATE TABLE STUDENT (RollNo INT PRIMARY KEY, Name VARCHAR(20) NOT NULL, Class CHAR(3), Marks INT, City VARCHAR(20));
INSERT INTO STUDENT VALUES (1, 'Asha', '12A', 88, 'Delhi');
UPDATE STUDENT SET Marks = Marks + 2 WHERE RollNo = 5;

⚠️ DELETE, DROP और छूटा हुआ WHERE
DELETE FROM STUDENT; हर पंक्ति हटाता है पर ख़ाली तालिका बनी रहती है — यह DML है। DROP TABLE STUDENT; स्वयं तालिका को, संरचना सहित, हटा देता है — यह DDL है। WHERE के बिना UPDATE या DELETE हर पंक्ति पर कार्य करता है, जो शायद ही कभी अभिप्रेत होता है।

SELECT से क्वेरी

आगे के सभी उदाहरण इस तालिका का प्रयोग करते हैं, जिसमें मीना के अंक दर्ज नहीं हुए हैं और NULL हैं:

तालिका: STUDENT
RollNoNameClassMarksCity
1Asha12A88Delhi
2Ravi12B72Pune
3Meena12ANULLDelhi
4Kabir12B91Jaipur
5Tara12A65Pune
  • SELECT Name, Marks FROM STUDENT WHERE City = 'Pune'; — स्तंभ चुनें, पंक्तियाँ छानें। SELECT * हर स्तंभ लेता है; DISTINCT दोहराए मान हटाता है (SELECT DISTINCT City 3 पंक्तियाँ देता है); AS आउटपुट में स्तंभ का नाम बदलता है।
  • संबंधपरक और तार्किक संक्रियक: =, <>, <, >, <=, >= तथा AND, OR और NOT।
  • BETWEEN a AND b दोनों सिरों को शामिल करता है: Marks BETWEEN 72 AND 88 आशा (88) और रवि (72) देता है।
  • IN (list) सदस्यता जाँचता है: City IN ('Pune', 'Jaipur')।
  • LIKE पैटर्न मिलाता है: % कितने भी वर्णों (शून्य सहित) के लिए और _ ठीक एक वर्ण के लिए। Name LIKE '_a%' — दूसरा अक्षर a — रवि, कबीर और तारा देता है।
  • NULL केवल IS NULL / IS NOT NULL से जाँचा जाता है; Marks = NULL कभी सत्य नहीं होता। NULL से हर तुलना अज्ञात है, अतः मीना Marks > 70 में विफल होती है — फिर भी Marks > 70 OR City = 'Delhi' उसे लौटाता है, क्योंकि दूसरी शर्त सत्य है।
  • ORDER BY column परिणाम को क्रमित करता है, डिफ़ॉल्ट रूप से आरोही; अवरोही के लिए DESC जोड़ें।

फ़ंक्शन, GROUP BY और HAVING

एकल-पंक्ति फ़ंक्शन — हर पंक्ति के लिए एक परिणाम
प्रकारफ़ंक्शन और उदाहरण
गणितीयPOWER(2, 3) → 8; ROUND(25.678, 1) → 25.7; MOD(17, 5) → 2
स्ट्रिंगUPPER('sql') / UCASE → SQL; LOWER / LCASE; LENGTH('India') → 5; LEFT('database', 4) → data; RIGHT('database', 4) → base; MID('Informatics', 3, 4) (SUBSTRING भी) → form; INSTR('computer', 'put') → 4; LTRIM, RTRIM, TRIM स्पेस हटाते हैं
तिथिNOW() वर्तमान तिथि व समय; DATE(), MONTH(), MONTHNAME(), YEAR(), DAY(), DAYNAME() भाग निकालते हैं — MONTHNAME('2024-08-15') → August

समुच्चय (aggregate) फ़ंक्शन पूरा स्तंभ लेकर एक मान लौटाते हैं: MAX, MIN, SUM, AVG और COUNT। ये NULL की अनदेखी करते हैं — STUDENT पर SUM(Marks) 316 है और AVG(Marks) 316 / 4 = 79.0000 (MySQL चार दशमलव स्थान दिखाता है), 316 / 5 नहीं। COUNT(*) पंक्तियाँ गिनता है, अतः 5 देता है, जबकि COUNT(Marks) गैर-NULL मान गिनता है और 4 देता है। GROUP BY समान मान वाली पंक्तियों के समूह बनाकर हर समूह पर समुच्चय फ़ंक्शन लगाता है: SELECT City, SUM(Marks) FROM STUDENT GROUP BY City; Delhi 88, Jaipur 91 और Pune 137 देता है। HAVING उन समूहों को छानता है, जैसे WHERE पंक्तियों को: SELECT Class, COUNT(*) FROM STUDENT GROUP BY Class HAVING COUNT(*) > 2; केवल 3 वाला 12A लौटाता है।

⚠️ समूहन से पहले WHERE, बाद में HAVING
समुच्चय फ़ंक्शन WHERE में नहीं आ सकता, क्योंकि WHERE किसी समूह के बनने से पहले अलग-अलग पंक्तियों पर लगता है। WHERE COUNT(*) > 2 त्रुटि है; HAVING COUNT(*) > 2 सही है। साधारण स्तंभ पर शर्त, जैसे Marks > 60, WHERE में आती है।

संबंधों पर संक्रियाएँ और जॉइन

संबंधों को समुच्चयों की तरह जोड़ा जा सकता है। UNION समान गुणों वाले दो संबंधों में से किसी में भी उपस्थित टपल देता है, बिना दोहराव के; INTERSECT दोनों में उपस्थित टपल; और MINUS (समुच्चय-अंतर) वे टपल जो पहले में हों पर दूसरे में नहीं। दो संबंधों का कार्तीय गुणनफल (Cartesian product) एक के हर टपल को दूसरे के हर टपल से जोड़ता है: इसकी डिग्री दोनों डिग्रियों का योग और कार्डिनैलिटी दोनों कार्डिनैलिटियों का गुणनफल है — 5 पंक्ति, 5 स्तंभ की तालिका और 3 पंक्ति, 2 स्तंभ की तालिका 7 स्तंभों की 15 पंक्तियाँ देती हैं।

जॉइन कार्तीय गुणनफल के केवल सार्थक जोड़े रखता है। इक्वी-जॉइन (equi-join) वे जोड़े रखता है जिनका साझा गुण बराबर हो: FEES(RollNo, Paid) तालिका के साथ SELECT S.Name, F.Paid FROM STUDENT S, FEES F WHERE S.RollNo = F.RollNo; हर शुल्क-रिकॉर्ड को उसके विद्यार्थी से जोड़ता है और * से दोनों चुनने पर साझा स्तंभ दो बार दिखाता है। प्राकृतिक जॉइन (NATURAL JOIN) समान नाम वाले स्तंभों पर स्वतः मिलान करता है और वह साझा स्तंभ केवल एक बार दिखाता है।

पायथन को MySQL से जोड़ना

पायथन प्रोग्राम mysql.connector मॉड्यूल से MySQL तक पहुँचता है। चरण सदैव वही हैं: मॉड्यूल import करें; host, user, password और database देकर connect() से कनेक्शन खोलें; कनेक्शन से एक कर्सर बनाएँ; cursor.execute(query) से SQL चलाएँ; fetchone() (अगली पंक्ति टपल के रूप में, या कुछ शेष न हो तो None), fetchmany(n) या fetchall() (सभी शेष पंक्तियाँ टपलों की सूची के रूप में) से परिणाम पढ़ें; और किसी भी INSERT, UPDATE या DELETE के बाद कनेक्शन पर commit() करें, अन्यथा परिवर्तन सहेजा नहीं जाता। cursor.rowcount पिछले कथन द्वारा प्राप्त या प्रभावित पंक्तियों की संख्या देता है।

एक पूरा उदाहरण जो तारा के अंक बढ़ाता है और फिर पुणे के विद्यार्थियों को वापस पढ़ता है:
import mysql.connector
con = mysql.connector.connect(host="localhost", user="root", password="xyz", database="school")
cur = con.cursor()
cur.execute("UPDATE STUDENT SET Marks = 70 WHERE RollNo = 5")
con.commit()
cur.execute("SELECT Name, Marks FROM STUDENT WHERE City = %s", ("Pune",))
for row in cur.fetchall():
print(row)
con.close()
मानों के टपल के साथ %s प्लेसहोल्डर कनेक्टर को मान सुरक्षित ढंग से डालने देता है, स्ट्रिंगें जोड़कर क्वेरी बनाने के बजाय।

मुख्य बिंदु

  • CHAR निश्चित-लंबाई है, VARCHAR परिवर्ती-लंबाई; PRIMARY KEY का अर्थ अद्वितीय और NOT NULL एक साथ।
  • DDL (CREATE, ALTER, DROP) संरचना बदलती है; DML (INSERT, UPDATE, DELETE) पंक्तियाँ। DELETE तालिका ख़ाली करता है, DROP उसे हटा देता है।
  • BETWEEN दोनों सिरे शामिल करता है; LIKE में % किसी भी वर्ण-क्रम और _ ठीक एक वर्ण के लिए; NULL केवल IS NULL से जाँचा जाता है।
  • समुच्चय फ़ंक्शन NULL की अनदेखी करते हैं: COUNT(*) पंक्तियाँ गिनता है, COUNT(column) गैर-NULL मान, AVG गैर-NULL संख्या से भाग देता है।
  • GROUP BY समूह बनाता है; HAVING समूह छानता है और समुच्चय फ़ंक्शन प्रयोग कर सकता है, WHERE पंक्तियाँ छानता है और नहीं कर सकता।
  • कार्तीय गुणनफल डिग्रियाँ जोड़ता और कार्डिनैलिटियाँ गुणा करता है; इक्वी-जॉइन समान साझा मान वाले जोड़े रखता है।
  • mysql.connector: connect(), cursor(), execute(), fetchone()/fetchall(), और किसी भी परिवर्तन के बाद commit()।

अभ्यास प्रश्न (8)

उत्तर खोलने से पहले प्रत्येक प्रश्न हल करें। हर व्याख्या सही विकल्प के साथ लुभावना गलत विकल्प भी बताती है, क्योंकि अंक वहीं जाते हैं।

  1. तालिका: STUDENT
    RollNoNameClassMarksCity
    1Asha12A88Delhi
    2Ravi12B72Pune
    3Meena12ANULLDelhi
    4Kabir12B91Jaipur
    5Tara12A65Pune

    ऊपर दी तालिका पर SELECT COUNT(*), COUNT(Marks) FROM STUDENT; का आउटपुट क्या है?

    1. 5 और 5
    2. 4 और 4
    3. 5 और 4
    4. 4 और 5
    उत्तर देखें

    उत्तर: C — 5 और 4

    COUNT() पंक्तियाँ गिनता है, उनमें जो भी हो, अतः 5 देता है। COUNT(Marks) उस स्तंभ के केवल गैर-NULL मान गिनता है, और मीना के अंक NULL हैं, अतः 4 देता है। पाँच और पाँच NULL को गिने जाने वाला मान मानता है; चार और चार NULL-नियम को COUNT() पर भी लगाता है, जो हर पंक्ति गिनता है।
  2. तालिका: STUDENT
    RollNoNameClassMarksCity
    1Asha12A88Delhi
    2Ravi12B72Pune
    3Meena12ANULLDelhi
    4Kabir12B91Jaipur
    5Tara12A65Pune

    ऊपर दी तालिका के लिए SELECT AVG(Marks) FROM STUDENT; क्या लौटाता है?

    1. 63.2000
    2. 79.0000
    3. NULL
    4. 316
    उत्तर देखें

    उत्तर: B — 79.0000

    AVG, NULL की अनदेखी करता है, अतः चार ज्ञात अंक 88 + 72 + 91 + 65 = 316 जोड़कर 4 से भाग देता है, परिणाम 79 (MySQL 79.0000 दिखाता है)। 63.2, 316 को पाँचों पंक्तियों से भाग देता है, मानो मीना ने शून्य पाया हो। एक NULL पूरे समुच्चय को NULL नहीं बनाता, और 316 योग (SUM) है, औसत नहीं।
  3. तालिका: STUDENT
    RollNoNameClassMarksCity
    1Asha12A88Delhi
    2Ravi12B72Pune
    3Meena12ANULLDelhi
    4Kabir12B91Jaipur
    5Tara12A65Pune

    ऊपर दी तालिका पर SELECT Name FROM STUDENT WHERE Name LIKE '_a%'; कौन-से नाम लौटाता है?

    1. आशा, मीना और तारा
    2. केवल आशा
    3. केवल रवि और तारा
    4. रवि, कबीर और तारा
    उत्तर देखें

    उत्तर: D — रवि, कबीर और तारा

    अंडरस्कोर ठीक एक वर्ण से और % उसके बाद कितने भी वर्णों से मेल खाता है, अतः पैटर्न वे नाम माँगता है जिनका दूसरा अक्षर a है: रवि, कबीर और तारा। आशा, मीना और तारा a पर समाप्त होने वाले नाम हैं, जो '%a' का परिणाम है। केवल आशा पैटर्न को "a से शुरू" पढ़ता है, और कबीर को छोड़ना चूकता है कि % लंबे नाम के शेष अक्षरों से भी मेल खाता है।
  4. तालिका: STUDENT
    RollNoNameClassMarksCity
    1Asha12A88Delhi
    2Ravi12B72Pune
    3Meena12ANULLDelhi
    4Kabir12B91Jaipur
    5Tara12A65Pune

    ऊपर दी तालिका पर SELECT Class, COUNT(*) FROM STUDENT GROUP BY Class HAVING COUNT(*) > 2; का आउटपुट क्या है?

    1. एक पंक्ति: 12A, 3
    2. दो पंक्तियाँ: 12A, 3 और 12B, 2
    3. एक पंक्ति: 12A, 2
    4. कोई पंक्ति नहीं, क्योंकि किसी कक्षा में अंकों वाले 2 से अधिक विद्यार्थी नहीं
    उत्तर देखें

    उत्तर: A — एक पंक्ति: 12A, 3

    GROUP BY Class दो समूह बनाता है, तीन पंक्तियों (आशा, मीना, तारा) वाला 12A और दो वाला 12B; HAVING केवल दो से अधिक वाले समूह रखता है, अतः एक पंक्ति, 12A और 3, बचती है। 12B भी दिखाना HAVING की अनदेखी है। COUNT(*) पंक्तियाँ गिनता है, अतः मीना के NULL अंक 12A को दो नहीं करते — वह तर्क COUNT(Marks) पर लागू होता।
  5. तालिका: STUDENT
    RollNoNameClassMarksCity
    1Asha12A88Delhi
    2Ravi12B72Pune
    3Meena12ANULLDelhi
    4Kabir12B91Jaipur
    5Tara12A65Pune

    ऊपर दी तालिका के लिए SELECT * FROM STUDENT WHERE Marks > 70 OR City = 'Delhi'; कितनी पंक्तियाँ लौटाता है?

    1. 3
    2. 2
    3. 4
    4. 5
    उत्तर देखें

    उत्तर: C — 4

    आशा (88), रवि (72) और कबीर (91) Marks > 70 को संतुष्ट करते हैं। मीना के अंक NULL हैं, अतः वह तुलना अज्ञात है, पर City = 'Delhi' सत्य है, और अज्ञात OR सत्य = सत्य — वह भी लौटती है, कुल 4। 3 उत्तर मीना को इस मान्यता से हटा देता है कि NULL वाली हर तुलना पंक्ति को बाहर कर देती है; वह AND के साथ सही होता, OR के साथ नहीं। तारा दोनों शर्तों में विफल है।
  6. निम्नलिखित में से कौन-सा SQL आदेश डेटा परिभाषा भाषा (DDL) का आदेश है?

    1. UPDATE
    2. INSERT
    3. DELETE
    4. ALTER
    उत्तर देखें

    उत्तर: D — ALTER

    ALTER TABLE तालिका की संरचना बदलता है — स्तंभ या कुंजी जोड़ना, हटाना या बदलना — और संरचना ही वह है जिसे DDL परिभाषित करती है। UPDATE, INSERT और DELETE सभी तालिका की रूपरेखा बदले बिना उसमें संग्रहित पंक्तियों पर कार्य करते हैं, जो उन्हें DML बनाता है। DELETE आम जाल है, क्योंकि यह DROP जैसा लगता है, पर केवल पंक्तियाँ हटाता है।
  7. MySQL में SELECT MID('Informatics', 3, 4); का आउटपुट क्या है?

    1. form
    2. orma
    3. nfor
    4. for
    उत्तर देखें

    उत्तर: A — form

    MID(string, position, length) में SQL स्थितियाँ 1 से गिनता है: I 1 है, n 2, f 3, अतः स्थिति 3 से चार वर्ण f, o, r, m हैं — form। nfor पायथन के सूचकांकन की तरह 0 से गिनता है, और orma एक स्थान बाद से शुरू होता है। for केवल तीन वर्ण लेता है, मानो तीसरा तर्क लंबाई के बजाय अंतिम स्थिति हो।
  8. एक पायथन प्रोग्राम mysql.connector से कर्सर के माध्यम से INSERT कथन चलाता है। कौन-सा कॉल नई पंक्ति को डेटाबेस में स्थायी बनाता है?

    1. cursor.fetchall()
    2. कनेक्शन ऑब्जेक्ट पर connection.commit()
    3. cursor.execute() दूसरी बार
    4. print(cursor.rowcount)
    उत्तर देखें

    उत्तर: B — कनेक्शन ऑब्जेक्ट पर connection.commit()

    execute() INSERT भेजता है, पर परिवर्तन तभी सहेजा जाता है जब कनेक्शन पर commit() कॉल हो; उसके बिना कनेक्शन बंद होने पर पंक्ति खो जाती है। fetchall() किसी SELECT के परिणाम पढ़ता है और कुछ नहीं बदलता, execute() फिर चलाने से प्रविष्टि केवल दोहराई जाती, और rowcount केवल बताता है कि पिछले कथन ने कितनी पंक्तियाँ प्रभावित कीं।