Php MySQL Select语句,其中的'IN'子句
我的表中当前有以下行:Php MySQL Select语句,其中的'IN'子句,php,sql,mysql,select,Php,Sql,Mysql,Select,我的表中当前有以下行: course_data: user_id days <-- This is a varchar column. 405 1,3,5 基本上,如果$day变量包含“1、3或5”,我希望省略包含用户405的那一行 例如,如果$day=1,它应该返回一个空查询,因为数字1在列1,3,5中 然而,我发现情况并非如此。即使$day=1,它仍然返回该行 它不返回行
course_data:
user_id days <-- This is a varchar column.
405 1,3,5
基本上,如果$day变量包含“1、3或5”,我希望省略包含用户405的那一行
例如,如果$day=1,它应该返回一个空查询,因为数字1在列1,3,5中
然而,我发现情况并非如此。即使$day=1,它仍然返回该行
它不返回行的唯一方法是如果$day=1,3,5。然而,我认为IN子句将获取变量的任何部分并将其应用于该列
有没有关于我做错了什么的见解?谢谢。删除in语句中的引号。语法是:
... WHERE column IN (1,2,3)
而且不像你用的那样
... WHERE column IN ('1,2,3')
另请参见中的,还有更多示例。天不包含字符串列表。它只有一根弦。字符串1,3,5是否在{'1'中的一个字符串内?答案显然是否定的。要么将days重构到另一个表中,要么准备进行更多的字符串操作您应该使用它对char字段进行部分匹配:
where days like '%1%'
编辑:VolkerK和Lukas Lalinsky都建议使用MySQL的find_in_set,这可能比喜欢更好。但是,以下关于规范化数据库的建议仍然适用
但是,不应在单个数据库字段中存储多个值。相反,考虑使用两个表:
course_data:
user_id
course_days:
user_id
day_number
然后,您将获得以下数据:
course_data:
user_id
405
course_days
user_id day_number
405 1
405 3
405 5
然后可以正确地查询此模式。例如:
select cd.user_id
from course_data as cd
where cd.user_id not in
(
select course_days.user_id
from course_days
where course_days.user_id = cd.user_id
and course_days.day_number = 1
)
或者,应该很接近;我不确定您要完成什么,也不确定模式的其余部分是什么样子,因此这是一个最好的猜测。如果我正确理解您的问题,您希望将varchar字段的内容视为逗号分隔的列表,并测试此列表是否不包含特定值。为此,您需要该函数。
但请记住,MySQL在这种情况下不能使用索引,您的查询将始终需要进行完整的表扫描。最好不要在单个列中存储结构化数据并对单个元素进行比较,而是像其他响应中建议的那样使用另一个表和联接。我认为您需要的查询是:
SELECT usrID, usrFirst, usrLast, usrEmail
FROM tblUsers
WHERE usrID NOT IN (
SELECT user_id
FROM course_data
WHERE find_in_set(?, days) > 0
)
ORDER BY usrID
<>但是你应该认真考虑数据库的正常化,这样每一天都有自己的行。我做错了什么。如果我使用:WHERE days IN 1,它会正确地删除它并返回一个空结果。但如果我使用:WHERE days IN 3,它不会返回空查询。我认为它应该删除查询,因为“3”在查询中?有什么想法吗?我猜这是因为它将1,3,5转换成一个以逗号结尾的int,然后看到它匹配。不确定为什么这不是原始帖子中给出的场景的公认答案-尽管我承认公认的答案提供了纠正不良编码习惯的建议。谢谢。你改变结构的想法是对的。我继续这样做了。谢谢。这是一个最好的猜测:另一个希望可行的想法是使用一个不存在的子查询,如中所述,而不是子查询%中的x,比如%会给出11来搜索1,所以它并不适合,所以这个答案并不适用于原始问题。theomega的答案似乎更适用于OP。
SELECT usrID, usrFirst, usrLast, usrEmail
FROM tblUsers
WHERE usrID NOT IN (
SELECT user_id
FROM course_data
WHERE find_in_set(?, days) > 0
)
ORDER BY usrID