MySQL—如果在表F上找不到记录,则从关系表A、B、C、D、E中选择数据

MySQL—如果在表F上找不到记录,则从关系表A、B、C、D、E中选择数据,mysql,sql,database,relational-database,Mysql,Sql,Database,Relational Database,我的数据库中有6个表:用户,课程,用户课程,讲座,用户讲座和参加。在标题中,我把它们称为A、B、C、D、E和F 作为学校项目的一部分,我正在为讲座创建一个参加系统,我需要运行一个查询,只选择那些用户尚未参加的讲座 users表包含有关用户的信息。其“表结构如下所示: id INT(10) USINGNED PRIMARY KEY AUTO_INCREMENT name VARCHAR(255) email VARCHAR(255) password VARCHAR(60) created_at

我的数据库中有6个表:
用户
课程
用户课程
讲座
用户讲座
参加
。在标题中,我把它们称为A、B、C、D、E和F

作为学校项目的一部分,我正在为讲座创建一个参加系统,我需要运行一个查询,只选择那些用户尚未参加的讲座

users
表包含有关用户的信息。其“表结构如下所示:

id INT(10) USINGNED PRIMARY KEY AUTO_INCREMENT
name VARCHAR(255)
email VARCHAR(255)
password VARCHAR(60)
created_at TIMESTAMP
updated_at TIMESTAMP
id  INT(10) UNSIGNED AUTO_INCREMENT
name VARCHAR(255)
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
course_id INT(10) UNSIGNED FOREIGN KEY
id INT(10)
starting_at DATETIME
ending_at DATETIME
course_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
courses
表是讲座的父表,其中包含有关讲座所属课程的信息。其“表结构如下所示:

id INT(10) USINGNED PRIMARY KEY AUTO_INCREMENT
name VARCHAR(255)
email VARCHAR(255)
password VARCHAR(60)
created_at TIMESTAMP
updated_at TIMESTAMP
id  INT(10) UNSIGNED AUTO_INCREMENT
name VARCHAR(255)
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
course_id INT(10) UNSIGNED FOREIGN KEY
id INT(10)
starting_at DATETIME
ending_at DATETIME
course_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
users\u courses
是用户和课程之间的关系表。它将用户链接到课程。其“表结构如下所示:

id INT(10) USINGNED PRIMARY KEY AUTO_INCREMENT
name VARCHAR(255)
email VARCHAR(255)
password VARCHAR(60)
created_at TIMESTAMP
updated_at TIMESTAMP
id  INT(10) UNSIGNED AUTO_INCREMENT
name VARCHAR(255)
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
course_id INT(10) UNSIGNED FOREIGN KEY
id INT(10)
starting_at DATETIME
ending_at DATETIME
course_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
讲座
表包含了用户应该参加的即将到来的讲座的信息。它的表结构如下所示:

id INT(10) USINGNED PRIMARY KEY AUTO_INCREMENT
name VARCHAR(255)
email VARCHAR(255)
password VARCHAR(60)
created_at TIMESTAMP
updated_at TIMESTAMP
id  INT(10) UNSIGNED AUTO_INCREMENT
name VARCHAR(255)
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
course_id INT(10) UNSIGNED FOREIGN KEY
id INT(10)
starting_at DATETIME
ending_at DATETIME
course_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
users\u讲座
表是用户和讲座之间的关系表。它将讲座链接到用户。其“表结构如下所示:

id INT(10) USINGNED PRIMARY KEY AUTO_INCREMENT
name VARCHAR(255)
email VARCHAR(255)
password VARCHAR(60)
created_at TIMESTAMP
updated_at TIMESTAMP
id  INT(10) UNSIGNED AUTO_INCREMENT
name VARCHAR(255)
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
course_id INT(10) UNSIGNED FOREIGN KEY
id INT(10)
starting_at DATETIME
ending_at DATETIME
course_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
attents
表包含有关出席用户的用户id、讲座id以及创建时间和更新时间的信息。其“表结构如下所示:

id INT(10) USINGNED PRIMARY KEY AUTO_INCREMENT
name VARCHAR(255)
email VARCHAR(255)
password VARCHAR(60)
created_at TIMESTAMP
updated_at TIMESTAMP
id  INT(10) UNSIGNED AUTO_INCREMENT
name VARCHAR(255)
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
course_id INT(10) UNSIGNED FOREIGN KEY
id INT(10)
starting_at DATETIME
ending_at DATETIME
course_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
user_id INT(10) UNSIGNED FOREIGN KEY
lecture_id INT(10) UNSIGNED FOREIGN KEY
created_at TIMESTAMP
updated_at TIMESTAMP
问题:

通过一个查询,是否可以只选择用户尚未参加的即将举行的讲座

以下是我尝试过的内容,但它不会返回任何行:

// PHP
$stmt = $pdo->prepare("
SELECT
courses.name AS course,
lectures.id AS id,
lectures.starting_at,
lectures.ending_at,
users.name AS user_name,
users_lectures.user_id
FROM lectures
LEFT JOIN users_courses ON users_courses.course_id = lectures.course_id
LEFT JOIN courses ON courses.id = users_courses.course_id
LEFT JOIN users_lectures ON users_lectures.lecture_id = lectures.id
LEFT JOIN users ON users.id = users_lectures.user_id
LEFT JOIN attends ON attends.lecture_id = users_lectures.lecture_id
WHERE users_lectures.user_id = :user_id
AND lectures.ending_at > DATE_SUB(CURRENT_TIMESTAMP, INTERVAL 1 MINUTE)
AND lectures.ending_at > DATE_ADD(CURRENT_TIMESTAMP, INTERVAL 1 MINUTE)
AND attends.lecture_id != users_lectures.lecture_id
AND attends.user_id != :user_id
ORDER BY lectures.starting_at DESC");
我是否遗漏了一些东西,或者以错误的方式思考了整个结构


很抱歉提供了这么长的文字,但我希望尽可能具体。任何帮助都将不胜感激:)

首先,您需要从想要返回的主题开始。那就是用户。因此,这将是您要从中选择的第一个表(注意:为简洁起见,请使用AS重命名表):

下一步将所需的数据链接在一起。取决于您想要的具体程度,将取决于您需要进行的连接数量(例如courseID与CourseName)

现在假设我们需要大量人类可读的数据,例如名称,我们将链接以下表格

LEFT OUTER JOIN users_lectures AS ul ON u.id = ul.userid
LEFT OUTER JOIN lectures AS l ON l.id = ul.lectureid
LEFT OUTER JOIN courses AS c ON c.id = l.courseid
LEFT OUTER JOIN attends AS a ON a.userid = u.id AND a.lectureid = l.id
最重要的是,要找到没有参加的人,他们将不在Attents表中,所以我们只需检查Attents值为null的人

WHERE a.userid IS NULL
作为旁注,在WHERE子句中,您不会得到任何结果

AND attends.lecture_id != users_lectures.lecture_id
因为你加入了这个声明

LEFT JOIN attends ON attends.lecture_id = users_lectures.lecture_id

它们相互矛盾

使用WHERE子句过滤左连接的表可以有效地将它们转换为内部连接。试着把你的限制转移到相关表格的ON子句上。按照我的理解重新表述问题:查找属于学生选择的课程(即,学生课程中有一条记录映射到讲座表格)但学生尚未参加(即,参加人数中没有记录)的讲座你理解得对谢谢你先生结果和我想的一样!