Join Three Tables
Relationship Path में सोचें
Three-table query कोई magical syntax नहीं; यह relationships की sequence है। Students, student_id से results से जुड़ते हैं; results, subject_code से subjects से जुड़ते हैं। Students में direct subject column आवश्यक नहीं।
School Lab Extend करें
CREATE TABLE subjects (
subject_code VARCHAR(10) PRIMARY KEY,
subject_name VARCHAR(60) NOT NULL
);
CREATE TABLE results (
student_id INT NOT NULL,
subject_code VARCHAR(10) NOT NULL,
marks DECIMAL(5,2) NOT NULL,
PRIMARY KEY (student_id, subject_code),
FOREIGN KEY (student_id)
REFERENCES join_students(student_id),
FOREIGN KEY (subject_code)
REFERENCES subjects(subject_code)
);
INSERT INTO subjects VALUES
('CSC', 'Computer Science'),
('MAT', 'Mathematics');
INSERT INTO results VALUES
(1, 'MAT', 86), (1, 'CSC', 91),
(2, 'MAT', 92), (3, 'CSC', 74),
(4, 'MAT', 89);Composite primary key same student–subject के two results रोकती है। One student फिर भी many subjects ले सकता है।
Verified Three-Table JOIN
SELECT s.student_name,
sub.subject_name,
r.marks
FROM join_students AS s
JOIN results AS r
ON r.student_id = s.student_id
JOIN subjects AS sub
ON sub.subject_code = r.subject_code
ORDER BY s.student_id, sub.subject_code;पाँच result records से पाँच rows मिलती हैं। Aarav दो subjects के कारण legitimately twice आता है। Vihaan का result नहीं, इसलिए inner join में हट जाता है।
Join Path पढ़ें और बनाएँ
- Report की required population से शुरू करें।
- Bridge या transaction table को foreign key से join करें।
- Descriptive master को next foreign key से join करें।
- Common columns qualify करें और केवल needed fields चुनें।
- हर one-to-many edge का row count effect predict करें।
Joined Grain को Safely Aggregate करें
SELECT s.student_id, s.student_name,
COUNT(r.subject_code) AS subjects_taken,
ROUND(AVG(r.marks), 2) AS average_marks
FROM join_students AS s
JOIN results AS r
ON r.student_id = s.student_id
GROUP BY s.student_id, s.student_name
ORDER BY s.student_id;Report grain define करें—one row per student। Attendance details जैसी दूसरी one-to-many table result rows multiply करके AVG/SUM corrupt कर सकती है। Different grains हों तो हर fact अलग aggregate करके join करें।
No-Result Students Preserve करें
SELECT s.student_name,
COUNT(r.subject_code) AS subjects_taken,
ROUND(AVG(r.marks), 2) AS average_marks
FROM join_students AS s
LEFT JOIN results AS r
ON r.student_id = s.student_id
GROUP BY s.student_id, s.student_name
ORDER BY s.student_id;Result key का COUNT Vihaan के लिए zero; AVG के पास non-NULL input नहीं, इसलिए NULL। Subject names भी चाहिए तो subjects को r.subject_code से LEFT JOIN करें ताकि optional chain optional रहे।
Debug और Optimize
- एक समय एक JOIN जोड़ें और हर step पर rows count करें।
- हर key की दोनों sides temporarily select करें।
- Composite keys और unique constraints जाँचें।
- Starting population बचानी हो तो optional-side filters ON में रखें।
- Foreign keys index करें: composite primary key results.student_id से शुरू होती है; subject-driven access के लिए separate subject_code index उपयोगी हो सकता है।
- Correctness tests के बाद EXPLAIN लें।
अभ्यास: class_name को fourth table की तरह जोड़ें; double-counting के बिना class average निकालें; every student और केवल Mathematics marks दिखाएँ, no-Mathematics students preserve रहें।
Official संदर्भ
- MySQL 8.4 Reference Manual: JOIN Clause
- MySQL 8.4: Nested Join Optimization
- MySQL 8.4: EXPLAIN Statement
Syntax और optimizer notes official MySQL 8.4 manual से जाँचे गए हैं। अपने schema और data पर plan तथा row count अवश्य test करें।