[英]Select all from table where another query retuns no results
I'm creating a register web application for someone and I want to make student search to add a student to the activities register slightly more accurate.我正在为某人创建一个注册 Web 应用程序,我想让学生搜索以将学生添加到活动注册中稍微准确一些。
At the moment my prepared statement is:目前我准备好的声明是:
("SELECT * FROM students WHERE first_name LIKE :pattern OR last_name LIKE :pattern OR id LIKE :pattern ORDER BY last_name ASC");
And that works great.这很好用。 I returns a list of all students that match the search query.
我返回与搜索查询匹配的所有学生的列表。 However after doing that query, for each row that returns I want to check if the students.id and $_GET['activity'] do not appear in the participants table already.
但是,在执行该查询之后,对于返回的每一行,我想检查 student.id 和 $_GET['activity'] 是否已经没有出现在参与者表中。
$_GET['activity'] is an ID from activities.id $_GET['activity'] 是来自 activity.id 的 ID
The final result I want is to display all students that are not already registered on that activity.我想要的最终结果是显示所有尚未注册该活动的学生。
Is this possible in one query?这在一个查询中是可能的吗? As if it is I'd rather do that then have to run a query on each returns result to see whether it should be displayed or not.
好像我宁愿这样做,然后必须对每个返回结果运行查询以查看是否应该显示它。
I have looked into INNER JOIN as I've used it before, but I don't feel that is what I need.我之前使用过 INNER JOIN ,但我认为这不是我所需要的。 My main issue is how to run that query to check if each result is in the participants table already.
我的主要问题是如何运行该查询以检查每个结果是否已经在参与者表中。
Hopefully that will make sense as I'm finding it hard to work out how to word it in my head.希望这是有道理的,因为我发现很难弄清楚如何在脑海中表达出来。
My table structure:我的表结构:
students - id PRIMARY KEY AI, first_name (varchar255), last_name (varchar255), dob (date)学生- id PRIMARY KEY AI, first_name (varchar255), last_name (varchar255), dob (date)
activities - id PRIMARY KEY AI, title (varchar255), description (varchar255)活动- id PRIMARY KEY AI,标题(varchar255),描述(varchar255)
participants - id PRIMARY KEY AI, student_id (INT), activity_id (INT)参与者- id PRIMARY KEY AI、student_id (INT)、activity_id (INT)
EDIT Updating this to use the three tables in the question编辑更新它以使用问题中的三个表
If you want all students who do NOT have a certain activity, you use a query pattern like this.如果您想要所有没有特定活动的学生,您可以使用这样的查询模式。 The
LEFT JOIN
retains all the records from the students
table, and places NULL
values in the columns from activities
where the ON
condition fails to match. LEFT JOIN
保留students
表中的所有记录,并将NULL
值放置在ON
条件不匹配的activities
的列中。 You then throw in a WHERE
condition to keep only those NULL
values.然后你抛出一个
WHERE
条件来只保留那些NULL
值。 Like so:像这样:
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 )
If your input is an activity_id
, it's even easier.如果您的输入是一个
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 )
As you've noticed, INNER JOIN
can't do this, because it leaves out the rows from the first table that don't match the ON condition.正如您所注意到的,
INNER JOIN
不能这样做,因为它会遗漏第一个表中与 ON 条件不匹配的行。 But those rows are the very ones you want, hence the LEFT JOIN ... WHERE ... IS NULL
.但是这些行正是您想要的行,因此
LEFT JOIN ... WHERE ... IS NULL
。
Beware some things:注意一些事情:
id
values.id
值。SELECT *
.SELECT *
。 Instead, name the columns you want in your result set.OR ... LIKE
clauses in your filter for the student table is not going to perform very well.OR ... LIKE
子句序列不会表现得很好。try this query试试这个查询
"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)
Here 'activity' is $_GET['activity'] .这里的 'activity' 是$_GET['activity'] 。
You could use a subquery to get the studentid
s that are registered for $_GET['activity']
, and then remove them from the returned rows using NOT IN
in your WHERE
condition.您可以使用子查询来获取为
$_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
where :activity
is the placeholder for $_GET['activity']
其中
:activity
是$_GET['activity']
的占位符
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.