একটি কোয়েরির ভেতর আরেকটি কোয়েরি – এটাই হলো সাবকোয়েরি (Subquery) বা ইনার কোয়েরি বা নেস্টেড কোয়েরি। সাবকোয়েরি সাধারণত WHERE ক্লজের মধ্যে বসে এবং মূল কোয়েরির জন্য প্রয়োজনীয় ডেটা সরবরাহ করে। এর মাধ্যমে আমরা জটিল যুক্তি একটি সহজবোধ্য উপায়ে প্রকাশ করতে পারি। সাবকোয়েরি SELECT, INSERT, UPDATE, DELETE – সব ধরনের DML অপারেশনের সাথেই ব্যবহার করা যায়। আজ আমরা সাবকোয়েরির নিয়মকানুন, প্রতিটি স্টেটমেন্টে ব্যবহার ও বাস্তব উদাহরণ শিখব।
পূর্বপ্রস্তুতি
- SQLite ইন্সটল থাকতে হবে (সিরিজের ৩য় পর্ব দেখুন)।
- আমরা
subquery_demo.dbনামে ডাটাবেস তৈরি করব, যেখানেCOMPANYও তার ব্যাকআপCOMPANY_BKPটেবিল থাকবে।
টার্মিনাল:
bash
sqlite3 subquery_demo.db
sql
-- COMPANY টেবিল CREATE TABLE COMPANY( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL ); INSERT INTO COMPANY VALUES (1, 'Paul', 32, 'California', 20000.00); INSERT INTO COMPANY VALUES (2, 'Allen', 25, 'Texas', 15000.00); INSERT INTO COMPANY VALUES (3, 'Teddy', 23, 'Norway', 20000.00); INSERT INTO COMPANY VALUES (4, 'Mark', 25, 'Rich-Mond', 65000.00); INSERT INTO COMPANY VALUES (5, 'David', 27, 'Texas', 85000.00); INSERT INTO COMPANY VALUES (6, 'Kim', 22, 'South-Hall', 45000.00); INSERT INTO COMPANY VALUES (7, 'James', 24, 'Houston', 10000.00); -- COMPANY_BKP টেবিল (একই কাঠামো, ব্যাকআপ হিসেবে) CREATE TABLE COMPANY_BKP( ID INT PRIMARY KEY NOT NULL, NAME TEXT NOT NULL, AGE INT NOT NULL, ADDRESS CHAR(50), SALARY REAL ); INSERT INTO COMPANY_BKP SELECT * FROM COMPANY;
- আউটপুট ফরম্যাট:
.header on,.mode column।
১. সাবকোয়েরি কী ও নিয়মাবলী
সাবকোয়েরি হলো প্যারেন্থেসিস ()-র মধ্যে আবদ্ধ একটি SELECT স্টেটমেন্ট, যা মূল SQL স্টেটমেন্টের একটি অংশ হিসেবে কাজ করে। এটি প্রথমে সম্পাদিত হয়, তারপর তার ফলাফল মূল কোয়েরিতে ব্যবহৃত হয়।
প্রধান নিয়ম:
- সাবকোয়েরি অবশ্যই প্রথম বন্ধনীর (parentheses) মধ্যে থাকতে হবে।
- সাবকোয়েরির
SELECTক্লজে সাধারণত একটি মাত্র কলাম থাকা উচিত, যদি না মূল কোয়েরি একাধিক কলামের সাথে তুলনা করে (এক্ষেত্রে জোড়ায় জোড়ায় মিলাতে হবে)। - সাবকোয়েরিতে
ORDER BYব্যবহার করা যায় না (মূল কোয়েরিতে ব্যবহার করতে হবে)। তবেGROUP BYব্যবহার করে একই ধরনের কাজ চালানো যায়। - যদি সাবকোয়েরি একাধিক সারি ফেরত দেয়, তবে শুধুমাত্র
IN,ANY,ALL-র মতো মাল্টি-ভ্যালু অপারেটর ব্যবহার করতে হবে।=একক মানের জন্য। BETWEENঅপারেটর সরাসরি সাবকোয়েরির সাথে ব্যবহার করা যায় না, তবে সাবকোয়েরির ভেতরেBETWEENব্যবহার করা যায়।
২. SELECT-এ সাবকোয়েরি
সবচেয়ে সাধারণ প্রয়োগ। একটি উদাহরণ: যেসব কর্মীর বেতন ৪৫,০০০-এর বেশি, তাদের আইডি সাবকোয়েরি দিয়ে বের করে সেই আইডিগুলো মূল টেবিল থেকে দেখানো।
sql
SELECT *
FROM COMPANY
WHERE ID IN (SELECT ID
FROM COMPANY
WHERE SALARY > 45000);
ফলাফল:
text
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 85000.0
এখানে সাবকোয়েরি (SELECT ID FROM COMPANY WHERE SALARY > 45000) প্রথমে ID 4 এবং 5 ফেরত দেয়, তারপর মূল SELECT তাদের সম্পূর্ণ তথ্য নিয়ে আসে।
সাবকোয়েরির সাথে =: যদি নিশ্চিত যে সাবকোয়েরি একটিমাত্র সারি ফেরত দেবে, তাহলে = ব্যবহার করা যায়। যেমন:
sql
SELECT * FROM COMPANY WHERE SALARY = (SELECT MAX(SALARY) FROM COMPANY);
এটি সর্বোচ্চ বেতনধারী কর্মীকে দেখাবে। MAX একটি একক মান দেয়, তাই = ব্যবহার করা নিরাপদ।
৩. INSERT-এ সাবকোয়েরি
সাবকোয়েরি ব্যবহার করে আপনি এক টেবিল থেকে ডেটা এনে আরেক টেবিলে ইনসার্ট করতে পারেন। এটি INSERT INTO ... SELECT স্টেটমেন্টের মাধ্যমে করা হয়।
সিনট্যাক্স:
sql
INSERT INTO target_table (column_list) SELECT column_list FROM source_table WHERE condition;
উদাহরণ: COMPANY টেবিল থেকে সব রেকর্ড COMPANY_BKP-তে কপি করা (ইতিমধ্যে করেছি, কিন্তু আবার দেখানো যাক):
sql
INSERT INTO COMPANY_BKP SELECT * FROM COMPANY WHERE ID IN (SELECT ID FROM COMPANY);
অথবা আরও ফিল্টার করে: শুধুমাত্র যাদের বয়স ২৫-এর বেশি তাদের ব্যাকআপ নিতে:
sql
INSERT INTO COMPANY_BKP SELECT * FROM COMPANY WHERE AGE IN (SELECT AGE FROM COMPANY WHERE AGE > 25);
৪. UPDATE-এ সাবকোয়েরি
আপডেটের WHERE ক্লজে সাবকোয়েরি ব্যবহার করে আপনি নির্দিষ্ট শর্তসাপেক্ষে রেকর্ড আপডেট করতে পারেন। আবার SET-এও সাবকোয়েরি ব্যবহার করা যায়।
উদাহরণ: COMPANY টেবিলে যেসব কর্মীর বয়স ২৭ বা তার বেশি, তাদের বেতন অর্ধেক করে দেওয়া। আমরা COMPANY_BKP থেকে সেই বয়সের তালিকা নিচ্ছি (একই টেবিল থেকেও নেওয়া যায়)।
sql
UPDATE COMPANY
SET SALARY = SALARY * 0.50
WHERE AGE IN (SELECT AGE FROM COMPANY_BKP
WHERE AGE >= 27);
ফলাফল: Paul (AGE 32) ও David (AGE 27) আপডেট হবে।
text
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 1 Paul 32 California 10000.0 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 42500.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0
৫. DELETE-এ সাবকোয়েরি
ডিলিটের WHERE ক্লজে সাবকোয়েরি ব্যবহার করে নির্দিষ্ট শর্তের ভিত্তিতে রেকর্ড মুছে ফেলা যায়।
উদাহরণ: COMPANY টেবিল থেকে তাদের মুছে ফেলি, যাদের বয়স ২৭-এর বেশি (অর্থাৎ ২৮ বা তার বেশি, বা বড়) – COMPANY_BKP থেকে সেই শর্তে বয়স বের করে।
sql
DELETE FROM COMPANY
WHERE AGE IN (SELECT AGE FROM COMPANY_BKP
WHERE AGE > 27);
ফলাফল: Paul (AGE 32) ডিলিট হবে। David (AGE 27) থাকবে, কারণ > 27 তে সে আসে না।
text
ID NAME AGE ADDRESS SALARY ---------- ---------- ---------- ---------- ---------- 2 Allen 25 Texas 15000.0 3 Teddy 23 Norway 20000.0 4 Mark 25 Rich-Mond 65000.0 5 David 27 Texas 42500.0 6 Kim 22 South-Hall 45000.0 7 James 24 Houston 10000.0
৬. সাবকোয়েরির প্রকারভেদ (সংক্ষেপ)
- স্কেলার সাবকোয়েরি: একটি মাত্র মান (এক কলাম, এক সারি) ফেরত দেয়।
=অপারেটরের সাথে ব্যবহার হয়। - রো সাবকোয়েরি: একাধিক কলাম ফেরত দেয়, তুলনার সময় কলাম সংখ্যা মিলাতে হয়।
- টেবিল সাবকোয়েরি: একাধিক কলাম ও সারি ফেরত দেয়,
IN,EXISTS,ANY,ALL-র সাথে ব্যবহার হয়।
৭. ডিরেক্টরি স্ট্রাকচার ও প্যাকেজ
ডাটাবেস ফাইল: subquery_demo.db। কোনো অতিরিক্ত প্যাকেজ ইন্সটল করতে হবে না।
text
project-folder/ └── subquery_demo.db
৮. গুরুত্বপূর্ণ টিপস
- সাবকোয়েরি সর্বদা বন্ধনীতে রাখুন।
- পারফরম্যান্স বিবেচনা: কখনো কখনো সাবকোয়েরির বদলে
JOINব্যবহার করলে দ্রুত ফলাফল পাওয়া যায়। জটিল সাবকোয়েরির বদলে JOIN বিবেচনা করুন। - একাধিক সারি পেলে
=নয়: যদি সাবকোয়েরি একাধিক সারি ফেরত দেয়, তাহলে=ব্যবহার করলে এরর আসবে।INব্যবহার করুন। - সাবকোয়েরিতে
ORDER BYনেই: সাজানোর প্রয়োজন হলে মূল কোয়েরিতেORDER BYব্যবহার করুন। EXISTSঅপারেটর: সাবকোয়েরির সারি আছে কিনা তা চেক করতেEXISTSব্যবহার করা যায়, যা অনেক সময়IN-এর চেয়ে দ্রুত কাজ করে।
৯. সম্পূর্ণ অনুশীলন সেশন
sql
.headers on .mode column -- প্রাথমিক টেবিল দেখি SELECT * FROM COMPANY; SELECT * FROM COMPANY_BKP; -- SELECT-এ সাবকোয়েরি: সবার বেতন থেকে বেশি বেতন যাদের SELECT * FROM COMPANY WHERE SALARY > (SELECT AVG(SALARY) FROM COMPANY); -- INSERT-এ সাবকোয়েরি: যাদের বয়স 30 এর নিচে, তাদের ব্যাকআপে কপি INSERT INTO COMPANY_BKP SELECT * FROM COMPANY WHERE AGE IN (SELECT AGE FROM COMPANY WHERE AGE < 30); -- UPDATE-এ সাবকোয়েরি: যাদের বয়স Mark-এর সমান তাদের বেতন 10% বাড়ান UPDATE COMPANY SET SALARY = SALARY * 1.10 WHERE AGE = (SELECT AGE FROM COMPANY WHERE NAME = 'Mark'); -- DELETE-এ সাবকোয়েরি: যাদের বেতন গড় বেতনের নিচে তাদের মুছে ফেলি (পরীক্ষা করে দেখতে পারেন, তবে আগে ব্যাকআপ নিন) -- DELETE FROM COMPANY WHERE SALARY < (SELECT AVG(SALARY) FROM COMPANY);
পরবর্তী পর্বে
আমরা শিখব SQLite AUTOINCREMENT – স্বয়ংক্রিয়ভাবে প্রাইমারি কি মান বৃদ্ধির কৌশল।
লেখকের কথা: সাবকোয়েরি SQL-এর জাদু! এটি আপনার ডেটাবেস প্রশ্নকে শক্তিশালী করে তোলে। বাংলায় এই টিউটোরিয়াল সিরিজ আপনার শেখার সঙ্গী হয়ে উঠুক। পোস্টটি ভালো লাগলে শেয়ার করুন, এবং সিরিজের সব আপডেট পেতে ToLearnTeam.com সাবস্ক্রাইব করুন। আপনার মতামত আমাদের অনুপ্রাণিত করে – কমেন্ট করতে ভুলবেন না!
SQLite Full Course
- SQLite পরিচিতি ও ইন্সটলেশন গাইড – বাংলায় প্রথম ডাটাবেস তৈরি
- SQLite কী এবং কেন শিখবেন? সম্পূর্ণ ওভারভিউ ও কমান্ড ক্লাসিফিকেশন (DDL, DML, DQL)
- SQLite ইন্সটলেশন গাইড – Windows, Linux ও Mac-এ ধাপে ধাপে সেটআপ
- SQLite ডট কমান্ড (Dot Commands) – সম্পূর্ণ গাইড, আউটপুট ফরম্যাট ও sqlite_master
- SQLite সিনট্যাক্স (Syntax) – কেস সেনসিটিভিটি, কমেন্ট, সব কমান্ডের গঠন ও উদাহরণ
- SQLite ডেটা টাইপ (Data Type) – স্টোরেজ ক্লাস, টাইপ অ্যাফিনিটি, বুলিয়ান ও ডেট-টাইম
- SQLite ডেটাবেস তৈরি (Create Database) – ধাপে ধাপে গাইড, .dump এক্সপোর্ট ও রিস্টোর
- SQLite ATTACH DATABASE – একাধিক ডাটাবেস সংযুক্ত করার সম্পূর্ণ গাইড (বাংলা)
- SQLite DETACH DATABASE – সংযুক্ত ডাটাবেস বিচ্ছিন্ন করার পূর্ণাঙ্গ গাইড
- SQLite CREATE TABLE স্টেটমেন্ট – টেবিল তৈরি করার পূর্ণাঙ্গ গাইড (বাংলা)
- SQLite DROP TABLE স্টেটমেন্ট – টেবিল ডিলিট করার সম্পূর্ণ গাইড (বাংলা)
- SQLite INSERT INTO স্টেটমেন্ট – ডেটা ইনসার্ট করার সম্পূর্ণ গাইড (বাংলা)
- SQLite SELECT স্টেটমেন্ট – টেবিল থেকে ডেটা ফেচ করার সম্পূর্ণ গাইড (বাংলা)
- SQLite অপারেটর (Operators) – Arithmetic, Comparison, Logical, Bitwise (বাংলা টিউটোরিয়াল)
- SQLite এক্সপ্রেশন (Expressions) – বুলিয়ান, নিউমেরিক ও ডেট এক্সপ্রেশন (বাংলা টিউটোরিয়াল)
- SQLite AND ও OR অপারেটর – একাধিক শর্ত দিয়ে ডেটা ফিল্টার (বাংলা টিউটোরিয়াল)
- SQLite UPDATE Query – টেবিলের ডেটা পরিবর্তন করার সম্পূর্ণ গাইড (বাংলা)
- SQLite DELETE Query – টেবিল থেকে ডেটা মুছে ফেলার সম্পূর্ণ গাইড (বাংলা)
- SQLite LIKE Operator – প্যাটার্ন মিলিয়ে ডেটা খোঁজার সম্পূর্ণ গাইড (বাংলা)
- SQLite GLOB Operator – কেস-সেনসিটিভ প্যাটার্ন মিলিয়ে ডেটা খোঁজা (বাংলা)
- SQLite LIMIT Clause – ডেটা সীমিত করে আনার সম্পূর্ণ গাইড (বাংলা)
- SQLite ORDER BY ক্লজ – ডেটা সাজানোর সম্পূর্ণ গাইড (বাংলা)
- SQLite GROUP BY ক্লজ – ডেটা গ্রুপ করে বিশ্লেষণ করার সম্পূর্ণ গাইড (বাংলা)
- SQLite HAVING ক্লজ – গ্রুপের উপর শর্ত দিয়ে ডেটা ফিল্টার (বাংলা টিউটোরিয়াল)
- SQLite DISTINCT Keyword – ডুপ্লিকেট ডেটা বাদ দিয়ে ইউনিক ভ্যালু পাওয়া (বাংলা)
- SQLite PRAGMA কমান্ড – ডাটাবেস কনফিগারেশন ও সেটিংস (বাংলা টিউটোরিয়াল)
- SQLite Constraints – NOT NULL, DEFAULT, UNIQUE, PRIMARY KEY, CHECK (বাংলা টিউটোরিয়াল)
- SQLite JOINS – CROSS JOIN, INNER JOIN, LEFT OUTER JOIN (বাংলা টিউটোরিয়াল)
- SQLite UNION ও UNION ALL – একাধিক SELECT একত্রিত করার সম্পূর্ণ গাইড (বাংলা)
- SQLite NULL Values – NULL কী, IS NULL, IS NOT NULL (বাংলা টিউটোরিয়াল)
- SQLite ALIAS Syntax – টেবিল ও কলামের অস্থায়ী নাম (বাংলা টিউটোরিয়াল)
- SQLite Triggers – স্বয়ংক্রিয় ট্রিগার তৈরি, ব্যবহার ও মুছে ফেলা (বাংলা টিউটোরিয়াল)
- SQLite Indexes – CREATE, UNIQUE, COMPOSITE, DROP INDEX (বাংলা টিউটোরিয়াল)
- SQLite INDEXED BY Clause – নির্দিষ্ট ইনডেক্স ব্যবহার ও NOT INDEXED (বাংলা)
- SQLite ALTER TABLE Command – টেবিলের গঠন পরিবর্তন (বাংলা টিউটোরিয়াল)
- SQLite TRUNCATE TABLE Command – DELETE ও DROP দিয়ে টেবিল খালি করা (বাংলা)
- SQLite Views – ভার্চুয়াল টেবিল তৈরি, ব্যবহার ও ডিলিট (বাংলা টিউটোরিয়াল)
- SQLite Transactions – BEGIN, COMMIT, ROLLBACK ও ACID প্রপার্টি (বাংলা)
- SQLite Subqueries – SELECT, INSERT, UPDATE, DELETE-এ সাবকোয়েরি ব্যবহার (বাংলা টিউটোরিয়াল)
- SQLite AUTOINCREMENT – স্বয়ংক্রিয়ভাবে প্রাইমারি কি মান বৃদ্ধি (বাংলা টিউটোরিয়াল)
- SQLite SQL Injection – কী, কেন বিপজ্জনক ও প্রতিরোধের উপায় (বাংলা টিউটোরিয়াল)
- SQLite EXPLAIN ও EXPLAIN QUERY PLAN – কোয়েরি বিশ্লেষণ (বাংলা টিউটোরিয়াল)
- SQLite VACUUM – ডাটাবেস পরিষ্কার, স্পেস রিক্লেইম ও অটো-ভ্যাকুয়াম (বাংলা টিউটোরিয়াল)
- SQLite Date & Time ফাংশন – date(), time(), datetime(), julianday(), strftime() (বাংলা টিউটোরিয়াল)
- SQLite Useful Functions – COUNT, MAX, MIN, AVG, SUM, RANDOM, ABS, UPPER, LOWER, LENGTH (বাংলা টিউটোরিয়াল)
- SQLite C/C++ প্রোগ্রামিং – sqlite3_open, exec, close, callback (বাংলা টিউটোরিয়াল)
- SQLite PHP প্রোগ্রামিং – PHP-তে SQLite ডাটাবেস ব্যবহার (বাংলা টিউটোরিয়াল)
- SQLite Perl প্রোগ্রামিং – DBI/DBD::SQLite দিয়ে ডাটাবেস অপারেশন (বাংলা)
- SQLite Python প্রোগ্রামিং – sqlite3 মডিউল দিয়ে CRUD অপারেশন (বাংলা টিউটোরিয়াল)
- SQLite Quick Guide – বাংলায় পূর্ণাঙ্গ সংক্ষিপ্ত টিউটোরিয়াল (শেখার সহজ গাইড)
