Bạn đang thiếu một bảng liên kết các đối tượng và sinh viên (mỗi điểm 2):
// student [student_id] takes subject [subject_id]
takes(student_id, subject_id)
Lưu ý rằng mỗi bảng cơ sở có một mẫu câu lệnh được liên kết cho các câu lệnh về tình hình kinh doanh, được tham số hóa bởi các tên cột - vị từ (đặc điểm) của nó . Các hàng làm cho vị ngữ true sẽ có trong bảng. Lưu ý rằng định nghĩa bảng trông giống như cách viết tắt cho vị ngữ.
// teacher [id] named [name] with email [email] teaches subject [subject_id]
teacher(id, name, email, subject_id)
// subject [id] named [name] is [description]
subject(id, name, description)
// student [id] named [name] lives at [location])
student(id, name, location)
// batch [id] at venue [venue] was taught by teacher [teacher_id] on date [date]
batch(id, venue, teacher_id, date)
// student-batch [id] reports student [student_id] being in batch [batch_id]
student-batch(id, student_id, batch_id)
// CHECK student [student_id] takes the subject that is taught by the teacher of batch [batch_id]
Vì bạn có vẻ bối rối về điều này, tôi sẽ rút ra nó về cách chúng ta có thể lập luận cho thiết kế bảng, ràng buộc và truy vấn. Một cách để thể hiện ràng buộc mà bạn muốn có vẻ là KIỂM TRA đã nhận xét ở trên.
Để thể hiện bất kỳ bảng, ràng buộc hoặc truy vấn nào trong SQL, trước tiên chúng ta quyết định về vị từ của nó. Sau đó, chúng ta có thể chuyển đổi vị ngữ sang tốc ký. Sau đó, chúng tôi có thể chuyển đổi tốc ký sang SQL.
Vị ngữ:
student [student_id] takes the subject that is taught by the teacher of batch [batch_id]
Sử dụng các vị từ trong bảng cơ sở:
FOR SOME k.*, t.*, b.* (
student_id = k.student_id AND batch_id = b.bid
AND student [k.student_id] takes subject [k.subject_id]
AND teacher [t.id] named [t.name] with email [t.email] teaches subject [t.subject_id]
AND batch [b.id] at venue [b.venue] was taught by teacher [b.teacher_id] on date [b.date]
AND [k.subject_id] = [t.subject_id]
AND [t.id] = [b.teacher_id])
Sử dụng các liên kết ngắn:
FOR SOME k.*, t.*, b.* (
student_id = k.student_id AND batch_id = b.bid
AND takes(k.student_id, k.subject_id)
AND teacher(t.id, t.name, t.email, t.subject_id)
AND batch(b.id, b.venue, b.teacher_id, date)
AND k.subject_id = t.subject_id
AND t.id = b.teacher_id)
Trong TỪ, mỗi bí danh (có thể ngầm định) đại diện cho một bảng giống như tên bảng cơ sở đã cho và / hoặc truy vấn con nhưng với mỗi cột trong giá trị &vị từ của nó được đổi tên thành bí danh . cột .
Chúng tôi nhận được các hàng thỏa mãn AND của hai vị từ bằng cách THAM GIA các bảng của vị từ trong SQL. Nếu chúng ta muốn các hàng thỏa mãn AND của một điều kiện thì chúng ta sử dụng ON hoặc WHERE trong SQL.
Mệnh đề SELECT trả về các hàng trong đó CHO MỘT SỐ giá trị của cột có dấu chấm mà các cột được trả về (không có dấu chấm) bằng chức năng của các cột có dấu chấm thỏa mãn vị từ FROM.
SQL:Thay thế các câu lệnh bằng bảng của chúng, AND bằng JOIN hoặc ON hoặc WHERE và bên ngoài FOR SOME &THERE EXISTS bằng SELECT:
SELECT t.student_id AS student_id, b.bid AS batch_id
FROM takes k JOIN teacher t JOIN batch b
WHERE k.subject_id = t.subject_id
AND t.id = b.teacher_id
AND student_id = t.student_id
AND batch_id = b.id
Bảng các hàng thỏa mãn OR của hai vị từ là UNION của bảng của chúng. Đối với VÀ KHÔNG, chúng tôi sử dụng EXCEPT (hay còn gọi là TRỪ) (hoặc thành ngữ THAM GIA TRÁI). Đối với MỘT SỐ hoặc CÓ TỒN TẠI trên tất cả các cột không thể được truy vấn trong SQL, nhưng nếu chúng ta muốn biết liệu có hàng nào đáp ứng một vị từ hay không thì chúng ta có thể sử dụng TỒN TẠI xung quanh một truy vấn con với vị từ đó.
Giả sử chúng ta muốn giới hạn một bảng cơ sở để mọi hàng thỏa mãn một vị từ trên một số cột. Tức là CHO TẤT CẢ các cột NẾU chúng thỏa mãn vị từ cơ sở THÌ chúng thỏa mãn vị từ truy vấn. Tức là CHO TẤT CẢ các cột NẾU hàng mà chúng tạo thành nằm trong cơ sở THÌ nó nằm trong truy vấn. Vì vậy, chúng tôi yêu cầu trong SQL là KHÔNG TỒN TẠI (CHỌN cột TỪ truy vấn ngoại trừ cơ sở). Hoặc đối với mỗi hàng trong cơ sở mà chúng tôi yêu cầu trong SQL TỒN TẠI (truy vấn).
Trong SQL tiêu chuẩn, bạn có thể TẠO KIỂM TRA ĐÁNH GIÁ (KHÔNG TỒN TẠI (SELECT student_id, batch_id TỪ truy vấn EXCEPT của sinh viên)) hoặc trong một loạt sinh viên CREATE TABLE, bạn có thể KIỂM TRA (EXISTS (truy vấn)). Thật không may, những điều này không được hỗ trợ bởi MySQL hoặc hầu hết các DBMS. Nếu bạn CHÈN vào hàng loạt sinh viên sau hàng loạt thì bạn có thể yêu cầu kích hoạt TỒN TẠI (truy vấn) đó. Hoặc bạn có thể thêm một số cột nhất định và ràng buộc FK tổng hợp (khóa ngoại).
Bây giờ chúng tôi đang viết một truy vấn. Chúng tôi muốn các hàng có:
FOR k.*, t.*, b.*, s.*, sb.* (
batch = b.id AND teacher = t.name AND student = s.name
AND takes(k.student_id, k.subject_id)
AND teacher(t.id, t.name, t.email, t.subject_id)
AND batch(b.id, b.venue, b.teacher_id, b.date)
AND student(s.id, s.name, s.location)
AND student-batch(sb.id, sb.student_id, sb.batch_id)
AND k.subject_id = t.subject_id
AND t.id = b.teacher_id
AND s.id = k.student_id
AND sb.student_id = k.student_id
AND sb.batch_id = b.id
AND @date = b.date)
Điều này trông giống như vị từ ràng buộc với các cột trả về khác nhau và các dòng được thêm vào. SQL cũng được dịch trực tiếp. Chúng tôi thêm tham gia với sinh viên để lấy tên sinh viên. Chúng tôi thêm một tham gia với lô sinh viên vì ràng buộc không giải quyết được nó; các ngữ cảnh sử dụng truy vấn ràng buộc kiểm tra xem các tiểu vùng của sinh viên (student_id, batch_id) có trong đó hay không.
SELECT b.id AS batch, t.name AS teacher, s.name AS student
FROM takes k JOIN teacher t JOIN batch b JOIN student s JOIN student-batch sb
WHERE ... AND @date = date
Bạn có thể thử phiên bản BẬT:
SELECT b.id AS Batch, t.name AS Teacher, s.name AS Student
FROM takes k
JOIN teacher t ON k.subject_id = t.subject_id
JOIN batch b ON t.id = b.teacher_id
JOIN ...
WHERE @date = b.date