我正在为某人创建一个注册 Web 应用程序,我想让学生搜索将学生添加到活动注册中稍微准确一些。
目前我准备好的声明是:
("SELECT * FROM students WHERE first_name LIKE :pattern OR last_name LIKE :pattern OR id LIKE :pattern ORDER BY last_name ASC");
这很好用。我返回与搜索查询匹配的所有学生的列表。但是,在执行该查询后,对于返回的每一行,我想检查 students.id 和 $_GET['activity'] 是否尚未出现在参与者表中。
$_GET['activity'] 是来自 activities.id 的 ID
我想要的最终结果是显示尚未在该活动中注册的所有学生。
这在一个查询中可能吗?好像是这样,我宁愿这样做,然后必须对每个返回结果运行查询以查看是否应该显示它。
我已经研究了INNER JOIN,因为我以前使用过它,但我觉得这不是我需要的。我的主要问题是如何运行该查询以检查每个结果是否已在参与者表中。
希望这是有道理的,因为我发现很难弄清楚如何在脑海中表达它。
我的表结构:
学生 - ID 主键 AI、first_name (VARCHAR255)、last_name (VARCHAR255)、DOB(日期)
活动 - ID 主键 AI、标题 (varchar255)、说明 (varchar255)
参与者 - ID 主键 AI、student_id(国际)、activity_id(国际)
编辑 更新此选项以使用问题中的三个表
如果您希望所有没有特定活动的学生,请使用这样的查询模式。LEFT JOIN
保留students
表中的所有记录,并将NULL
值放在ON
条件不匹配的activities
列中。然后,您提出一个WHERE
条件以仅保留这些NULL
值。这样:
SELECT s.id, s.first_name, s.last_name
FROM students s
LEFT JOIN participants p ON s.id = p.student_id
LEFT JOIN activities a ON p.activity_id = a.activity_id AND a.activity LIKE :act
WHERE a.activity_id IS NULL
AND ( s.first_name LIKE :a OR s.last_name LIKE :b OR etc etc )
如果您的输入是activity_id
,那就更容易了。
SELECT s.id, s.first_name, s.last_name
FROM students s
LEFT JOIN participants p ON s.id = p.student_id AND p.activity_id = :act
WHERE p.activity_id IS NULL
AND ( s.first_name LIKE :a OR s.last_name LIKE :b OR etc etc )
正如您所注意到的,INNER JOIN
不能这样做,因为它省略了第一个表中与 ON 条件不匹配的行。但是这些行正是您想要的行,因此LEFT JOIN ... WHERE ... IS NULL
.
当心一些事情:
- 不要使用 LIKE 来匹配
id
值。 - 不要使用
SELECT *
.相反,请命名结果集中所需的列。 - 学生表筛选器中的
OR ... LIKE
子句序列不会很好地执行。
子查询来获取为 $_GET['activity']
注册的 studentid
,然后在WHERE
条件下使用 NOT IN
将它们从返回的行中删除。
SELECT * FROM students
WHERE
(first_name LIKE :pattern OR last_name LIKE :pattern OR id LIKE :pattern)
AND
id NOT IN
(SELECT student_id FROM participants WHERE activity_id = :activity)
ORDER BY last_name ASC
其中:activity
是$_GET['activity']
的占位符
尝试此查询
"SELECT * FROM students WHERE first_name LIKE :pattern OR last_name LIKE :pattern OR id LIKE :pattern AND id NOT IN (select student_id From participants WHERE activity_id = activity)
这里的"活动"是 $_GET["活动"]。