我被困在mySQL查询上,我无法理解。我目前正在编写一个有助于解决教科书问题的PHP程序。我有一个带有2个表的mySQL数据库。
Books table
PID ISBN BKNAME CID
Issued table
PID SNR ISBN CAMPUSNR DATE
在学生编号中发布书籍类型的人以及学生必须为他注册的课程收到的所有书籍都会显示出来。像这样:
$stmt = $db->prepare("SELECT isbn,bkname,cid FROM books WHERE (cid = :course)");
$stmt->bindValue(':course', $StudCourse, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
这会显示在屏幕上,每本书后面都有一个复选框。然后发行人勾选他给学生的书籍,然后点击问题按钮。然后将此数据插入数据库,如下所示:
$stmt = $db->prepare("INSERT INTO issued(snr,isbn,campusnr,date) VALUES (:snr,:isbn,:campusnr,:date)");
$stmt->bindValue(':snr', $Studnr, PDO::PARAM_INT);
$stmt->bindValue(':isbn',$Ticked[$Num], PDO::PARAM_INT);
$stmt->bindValue(':campusnr', $Campus, PDO::PARAM_INT);
$stmt->bindValue(':date', $IssueDate, PDO::PARAM_STR);
问题在于,如果稍后要向运行第一个陈述的学生发放更多书籍,则会导致错误,如果发行人在书籍之后勾选了错误的方框,则可能会再次发出相同的书籍。
有没有办法在第一个陈述中只显示仍然需要发行的书籍。我尝试了以下mySQL语句:
SELECT *
FROM books
INNER JOIN issued ON books.isbn = issued.isbn
WHERE snr = '151107549'
AND NOT EXISTS (
SELECT isbn, bkname, cid
FROM books
WHERE cid = 'NC3OA'
)
但有了这个我没有结果。 mySQL专家可以提供一些帮助吗?
答案 0 :(得分:2)
SELECT books.isbn,books.bkname,books.cid
FROM books
LEFT JOIN issued ON books.isbn = issued.isbn AND issued.snr = :snr
WHERE books.cid = :course AND issued.isbn IS NULL
ORDER BY books.isbn ASC
答案 1 :(得分:1)
看看这个解释JOIN
s:
您希望books
中的所有行都具有特定的cid
。现在要从issued
中删除行,您可以LEFT JOIN
检查密钥是否为NULL
:
SELECT books.isbn, books.bkname, books.cid FROM books
LEFT JOIN issued
ON books.isbn = issued.isbn
WHERE cid = :course
AND issued.isbn IS NULL
答案 2 :(得分:1)
你在这里使用NOT EXISTS是正确的,因为你正在寻找那些尚无问题存在的书籍。但是,您没有正确使用EXISTS子句。你问:如果在数据库中没有带有cid NC3OA的书籍,只给我结果,所以你永远不会得到任何记录。 (不知何故,你的陈述看起来很混乱;内部联接会给你发行的而不是非发行的书。)
我的理解是:除了那些已经发给学生的书籍之外,你想要某本课程的所有书籍。这是正确的陈述:
SELECT *
FROM books
WHERE cid = 'NC3OA'
AND NOT EXISTS
(
SELECT *
FROM issued
WHERE issued.isbn = books.isbn
AND snr = '151107549'
);