বাস্তব ডাটাবেসে ডেটা ছড়িয়ে থাকে একাধিক টেবিলে। এই টেবিলগুলোর মধ্যে সম্পর্ক স্থাপন করে একসাথে তথ্য বের করার জন্য JOIN ক্লজ ব্যবহৃত হয়। JOIN একাধিক টেবিলের সাধারণ কলামের মানের ভিত্তিতে সারিগুলোকে যুক্ত করে একটি সম্মিলিত ফলাফল তৈরি করে। SQLite প্রধানত তিন ধরনের JOIN সমর্থন করে: CROSS JOIN, INNER JOIN, এবং LEFT OUTER JOIN। আজকের পর্বে আমরা COMPANY ও DEPARTMENT টেবিলের মাধ্যমে প্রতিটি JOIN-এর ধারণা, সিনট্যাক্স ও ব্যবহারিক উদাহরণ বিস্তারিত শিখব।
পূর্বপ্রস্তুতি
- SQLite ইন্সটল থাকতে হবে (সিরিজের ৩য় পর্ব দেখুন)।
- দুটি টেবিল প্রয়োজন:
COMPANY(কর্মী) এবংDEPARTMENT(বিভাগ)। এগুলোjoins.dbনামে তৈরি করি।
টার্মিনালে ডাটাবেস প্রস্তুত করুন:
bash
sqlite3 joins.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); -- DEPARTMENT টেবিল CREATE TABLE DEPARTMENT( ID INT PRIMARY KEY NOT NULL, DEPT CHAR(50) NOT NULL, EMP_ID INT NOT NULL ); INSERT INTO DEPARTMENT VALUES (1, 'IT Billing', 1); INSERT INTO DEPARTMENT VALUES (2, 'Engineering', 2); INSERT INTO DEPARTMENT VALUES (3, 'Finance', 7);
- আউটপুট ফরম্যাট:
.header onও.mode column।
গুরুত্বপূর্ণ সম্পর্ক: DEPARTMENT.EMP_ID কলামটি COMPANY.ID-র সাথে সম্পর্কিত (ফরেন কি-র মতো কাজ করছে)।
১. CROSS JOIN – সব কিছুর সাথে সব কিছু
CROSS JOIN প্রথম টেবিলের প্রতিটি সারির সাথে দ্বিতীয় টেবিলের প্রতিটি সারি মিলিয়ে একটি কার্তেসীয় গুণফল (Cartesian product) তৈরি করে। যদি প্রথম টেবিলে x সারি ও দ্বিতীয় টেবিলে y সারি থাকে, ফলাফলে x*y সারি হবে। বিশাল টেবিলের জন্য এটি বিপজ্জনক হতে পারে, তাই সাবধানে ব্যবহার করতে হবে।
সিনট্যাক্স:
sql
SELECT column_list FROM table1 CROSS JOIN table2;
আমাদের উদাহরণ:
sql
SELECT EMP_ID, NAME, DEPT FROM COMPANY CROSS JOIN DEPARTMENT;
এখানে CROSS JOIN-এর ফলে COMPANY-র ৭টি ও DEPARTMENT-এর ৩টি সারির গুণফলে মোট ২১টি সারি আসবে। প্রতিটি কর্মীর সাথে প্রতিটি বিভাগ যুক্ত হবে।
আংশিক ফলাফল:
text
EMP_ID NAME DEPT ---------- ---------- ---------- 1 Paul IT Billing 2 Paul Engineering 7 Paul Finance 1 Allen IT Billing 2 Allen Engineering 7 Allen Finance ...
কখন ব্যবহার করবেন: যখন আপনার সত্যিই সব কম্বিনেশন দরকার হয় (যেমন ম্যাট্রিক্স তৈরি বা টেস্ট ডেটা জেনারেশন)। সাধারণত WHERE বা ON শর্ত ছাড়া CROSS JOIN কম ব্যবহার হয়; বাস্তবে INNER JOIN-ই বেশি প্রয়োজনীয়।
২. INNER JOIN – সাধারণ কলামের ভিত্তিতে মিল
INNER JOIN সবচেয়ে বেশি ব্যবহৃত JOIN। এটি দুটি টেবিলের মধ্যে একটি শর্ত (join-predicate) পূরণ করলে তবেই সারি মিলিয়ে ফলাফল আনে। যে সারিগুলো শর্ত পূরণ করতে পারে না, সেগুলো বাদ যায়।
সিনট্যাক্স:
sql
SELECT column_list FROM table1 [INNER] JOIN table2 ON table1.column = table2.column;
INNER কীওয়ার্ডটি ঐচ্ছিক; শুধু JOIN লিখলেও INNER JOIN হবে।
আমাদের উদাহরণ: কর্মী ও তাদের বিভাগ দেখতে চাই, যেখানে COMPANY.ID = DEPARTMENT.EMP_ID:
sql
SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID;
ফলাফল:
text
EMP_ID NAME DEPT ---------- ---------- ---------- 1 Paul IT Billing 2 Allen Engineering 7 James Finance
শুধুমাত্র Paul, Allen, James-এর তথ্য এসেছে – কারণ কেবল তাদেরই ID-র সাথে DEPARTMENT-এ EMP_ID মিলেছে। Teddy, Mark, David, Kim DEPARTMENT-এ নেই, তাই তারা বাদ পড়েছে।
USING অপারেটর: যদি দুটি টেবিলের কলামের নাম একই হয়, তাহলে USING দিয়ে সংক্ষেপে লেখা যায়:
sql
SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT USING (ID);
কিন্তু এখানে আমাদের COMPANY-তে ID, আর DEPARTMENT-তে EMP_ID ভিন্ন নাম, তাই ON ব্যবহার করতে হয়েছে। যদি DEPARTMENT-তে কলামের নামও ID হতো, তাহলে USING (ID) চলত।
NATURAL JOIN: স্বয়ংক্রিয়ভাবে দুটি টেবিলের সব সাধারণ কলামের সমতার ভিত্তিতে INNER JOIN করে। এটি ব্যবহারে সাবধান থাকবেন, কারণ টেবিলের সব সাধারণ কলাম মিলবে। আমাদের টেবিলে ID সাধারণ কলাম (কিন্তু তারা ভিন্ন অর্থ বহন করে), তাই ভুল ফল দিতে পারে। তাই বাস্তবে ON বা USING-ই নির্ভরযোগ্য।
৩. LEFT OUTER JOIN – বাম টেবিলের সব সারি রাখো
LEFT OUTER JOIN INNER JOIN-এর সম্প্রসারণ। এটি বাম পাশের টেবিলের (প্রথম টেবিল) সব সারি রাখে, এমনকি ডান পাশের টেবিলে মিল না থাকলেও। যেখানে মিল নেই, সেখানে ডান টেবিলের কলামগুলো NULL হয়ে আসে।
সিনট্যাক্স:
sql
SELECT column_list FROM table1 LEFT [OUTER] JOIN table2 ON table1.column = table2.column;
OUTER কীওয়ার্ডটি ঐচ্ছিক।
আমাদের উদাহরণ: সব কর্মী এবং তাদের বিভাগ (থাকলে), না থাকলে NULL:
sql
SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID;
ফলাফল:
text
EMP_ID NAME DEPT
---------- ---------- ----------
1 Paul IT Billing
2 Allen Engineering
Teddy
Mark
David
Kim
7 James Finance
Teddy, Mark, David, Kim-এর কোনো বিভাগ নেই, তাই তাদের EMP_ID ও DEPT কলামে NULL বসেছে। কিন্তু তারা বাদ যায়নি। LEFT JOIN তখনই ব্যবহার হয় যখন আপনি মূল টেবিলের প্রতিটি রেকর্ড দেখতে চান, সাথে সম্পর্কিত টেবিলের তথ্য থাকলে তা দেখতে চান।
SQLite-তে RIGHT JOIN ও FULL JOIN নেই: SQLite শুধুমাত্র LEFT OUTER JOIN সমর্থন করে। RIGHT JOIN-এর প্রয়োজন হলে টেবিল দুটির অবস্থান অদলবদল করে LEFT JOIN ব্যবহার করতে হয়। FULL JOIN সরাসরি নেই, তবে UNION ব্যবহার করে মিমিক করা যায় (পরের পর্বে UNION আলোচিত হবে)।
৪. JOIN-এর সাথে অন্যান্য ক্লজ
JOIN-এর সাথে WHERE, GROUP BY, ORDER BY ইত্যাদি স্বাভাবিকভাবেই ব্যবহার করা যায়।
উদাহরণ: যেসব কর্মীর বিভাগ আছে, তাদের নাম ও বেতন বিভাগের নামসহ দেখাও এবং বেতন অনুযায়ী সাজাও:
sql
SELECT COMPANY.NAME, COMPANY.SALARY, DEPARTMENT.DEPT FROM COMPANY INNER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID ORDER BY COMPANY.SALARY DESC;
টেবিল অ্যালিয়াস: টেবিলের নাম বড় হলে অ্যালিয়াস ব্যবহার করাই ভালো:
sql
SELECT c.NAME, c.SALARY, d.DEPT FROM COMPANY AS c INNER JOIN DEPARTMENT AS d ON c.ID = d.EMP_ID;
৫. JOIN-গুলোর পার্থক্য একনজরে
| JOIN প্রকার | ফলাফল |
|---|---|
| CROSS JOIN | প্রতিটি সারির সাথে প্রতিটি সারি (x*y সারি) |
| INNER JOIN | শুধু মিলযুক্ত সারি |
| LEFT OUTER JOIN | বাম টেবিলের সব সারি + ডানের মিল (না থাকলে NULL) |
৬. ডিরেক্টরি স্ট্রাকচার ও প্যাকেজ
আমাদের এই অনুশীলনের জন্য joins.db নামে একটি ডাটাবেস ফাইল যথেষ্ট:
text
project-folder/ └── joins.db
কোনো অতিরিক্ত প্যাকেজ ইন্সটল করতে হবে না।
৭. গুরুত্বপূর্ণ টিপস
- সর্বদা ON/USING দিন: INNER JOIN বা LEFT JOIN-এ শর্ত না দিলে তা CROSS JOIN-এর মতো আচরণ করতে পারে, যা অনাকাঙ্ক্ষিত বিশাল ফলাফল তৈরি করে।
- কোন কলাম মিলবে বুঝুন: JOIN-এর আগে টেবিলের স্কিমা জেনে নিন, নাহলে ভুল কলাম মিলিয়ে অর্থহীন ফলাফল আসতে পারে।
- অ্যালিয়াস ব্যবহার করুন:
COMPANY.IDওDEPARTMENT.EMP_ID-র মতো লম্বা রেফারেন্সের বদলে অ্যালিয়াস দিলে কোয়েরি পড়তে সুবিধা হয়। - LEFT JOIN বনাম INNER JOIN: যদি মূল টেবিলের কোনো রেকর্ড হারাতে না চান, LEFT JOIN ব্যবহার করুন। ডেটা অ্যানালাইসিসে এটি বেশি নিরাপদ।
- NULL চেক: LEFT JOIN-এর ফলে NULL আসতে পারে; WHERE-এ
IS NULLবাIS NOT NULLদিয়ে ফিল্টার করুন (যেমন, “যাদের কোনো বিভাগ নেই”)।
৮. সম্পূর্ণ অনুশীলন সেশন
টার্মিনালে joins.db খুলে নিচের কোয়েরিগুলো চালান:
sql
.headers on .mode column -- CROSS JOIN: মোট 21 সারি SELECT COUNT(*) FROM COMPANY CROSS JOIN DEPARTMENT; -- INNER JOIN: মিলযুক্ত 3 সারি SELECT c.NAME, d.DEPT FROM COMPANY c INNER JOIN DEPARTMENT d ON c.ID = d.EMP_ID; -- LEFT JOIN: সব কর্মী (7 সারি), NULL সহ SELECT c.NAME, d.DEPT FROM COMPANY c LEFT JOIN DEPARTMENT d ON c.ID = d.EMP_ID; -- যাদের কোনো বিভাগ নেই (LEFT JOIN + NULL চেক) SELECT c.NAME FROM COMPANY c LEFT JOIN DEPARTMENT d ON c.ID = d.EMP_ID WHERE d.EMP_ID IS NULL; -- বেতন ২০০০০-এর বেশি ও বিভাগ আছে SELECT c.NAME, c.SALARY, d.DEPT FROM COMPANY c INNER JOIN DEPARTMENT d ON c.ID = d.EMP_ID WHERE c.SALARY > 20000;
পরবর্তী পর্বে
আমরা শিখব SQLite UNION অপারেটর – একাধিক SELECT-এর ফলাফলকে একত্রে জোড়া দেওয়ার কৌশল।
লেখকের কথা: JOIN ছাড়া রিলেশনাল ডাটাবেসের প্রকৃত শক্তি পাওয়া যায় না। বাংলায় এই টিউটোরিয়াল সিরিজ চলমান রাখতে আপনার উৎসাহ অপরিসীম। পোস্টটি ভালো লাগলে বন্ধুদের সাথে শেয়ার করুন এবং নিয়মিত আপডেট পেতে 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 – বাংলায় পূর্ণাঙ্গ সংক্ষিপ্ত টিউটোরিয়াল (শেখার সহজ গাইড)
