简体   繁体   English

MySQL查询不存在

[英]mySQL Query NOT EXISTS

I am stuck on a mySQL query that I just can't get my head around. 我被困在一个mySQL查询上,我只是无法理解。 I am currently writing a PHP program that will help with the issue of textbooks. 我目前正在编写一个PHP程序,可以帮助解决教科书问题。 I have a mySQL database with 2 tables. 我有一个带有2个表的mySQL数据库。

Books  table 
PID   ISBN   BKNAME  CID

Issued table
PID SNR ISBN CAMPUSNR DATE

The person issuing the books types in a student number and all the books that the student must receive for the course that he is enrolled in gets displayed. 发行书籍的人将输入学生编号,并显示该学生必须为其注册的课程收到的所有书籍。 Like this: 像这样:

  $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);

This gets displayed on screen with a checkbox after each book. 每本书后面都会在屏幕上显示一个复选框。 The issuer then ticks the books that he is giving the student and then clicks on a issue button. 然后,发行人在他给学生的书上打勾,然后单击发行按钮。 This data is then inserted in the database, like this: 然后将此数据插入数据库中,如下所示:

$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);

The problem with this is that if more books are to be issued later to the student running the first statement, leads to an error where the same books may be issued again if the issuer ticks the wrong box after the books. 这样做的问题是,如果以后要向运行第一条语句的学生发行更多的书,则会导致错误,如果发行人在书后的方框中打错了错误,则可能再次发行同一本书。

Is there a way to display in the first statement only the books still needed to be issued. 有没有一种方法可以在第一个语句中仅显示仍需要发行的书籍。 I have tried the following mySQL statement: 我已经尝试了以下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'
    )

But with this I get no results. 但是,我没有任何结果。 Can a mySQL guru maybe give some help? MySQL专家可能会提供一些帮助吗?

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

Take a look at this great figure explaining JOIN s: 看看这个解释JOIN的伟大人物:

在此处输入图片说明

You want all rows from books with a specific cid . 您希望books具有特定cid所有行。 Now to remove the rows from issued , you can do a LEFT JOIN with a check if the key is NULL : 现在要从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

You are right to use NOT EXISTS here, for you are looking for those books where no issue entry exists yet. 你是正确使用NOT EXISTS这里,你正在寻找在没有问题的条目还存在那些书。 However, you are not using the EXISTS clause correctly. 但是,您没有正确使用EXISTS子句。 You are asking: Give me only results if there exist no books with cid NC3OA in the database, so you never get any record. 您在问:如果数据库中没有cid NC3OA的书籍,请只给我结果,因此您永远不会获得任何记录。 (And somehow your statement looks quite confused; the inner join would give you the issued rather than the non-issued books.) (以某种方式您的陈述看起来很混乱;内部联接将为您提供已发行而不是未发行的书。)

What I understand is: You want all books for a certain course except those that are already issued to the student. 我的理解是:您希望某门课程的所有书籍都已发行给学生。 Here is the correct statement: 这是正确的声明:

SELECT * 
FROM books 
WHERE cid = 'NC3OA'
AND NOT EXISTS
(
  SELECT *
  FROM issued 
  WHERE issued.isbn = books.isbn
  AND snr =  '151107549'
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM