MySQL Select 语句,WHERE 'IN' 子句
Posted
技术标签:
【中文标题】MySQL Select 语句,WHERE \'IN\' 子句【英文标题】:MySQL Select Statement, WHERE 'IN' ClauseMySQL Select 语句,WHERE 'IN' 子句 【发布时间】:2010-12-07 20:24:12 【问题描述】:我的表中目前有以下行:
course_data:
user_id days <-- This is a varchar column.
405 1,3,5
我正在尝试实现以下 SELECT 语句:
SELECT usrID, usrFirst, usrLast, usrEmail
FROM tblUsers
WHERE usrID NOT IN
(
SELECT users.usrID
FROM
`course_data` courses,
`tblUsers` users
WHERE
days IN ('$day')
)
GROUP BY usrID
ORDER BY usrID
基本上,如果 $day 变量包含“1、3 或 5”,我希望省略该行(用户为 405)。
例如,如果$day = "1"
,它应该返回一个空查询(因为数字“1”在“1,3,5”列中)。
但是,我没有发现这种情况。即使$day = "1"
,它仍然返回该行。
它不会返回该行的唯一方法是 $day= "1,3,5."
但是,我认为 IN() 子句会占用我的变量的任何部分并将其应用于该列。
对我在这里做错了什么有任何见解吗?谢谢。
【问题讨论】:
【参考方案1】:删除 IN 语句中的引号。语法是:
... WHERE column IN (1,2,3)
而不是像你使用的那样
... WHERE column IN ('1,2,3')
另见 IN 上的documentation,还有更多示例。
【讨论】:
其实,抱歉,我需要澄清一下。我在这里做错了什么。如果我使用:WHERE days IN (1),它会正确删除它并返回一个空结果。但是如果我使用:WHERE days IN (3),它不会返回一个空查询。我认为它应该删除查询,因为“3”在查询中?有什么想法吗? 我猜这是因为它将“1,3,5”转换为int(停在逗号处),然后发现它匹配。 不知道为什么这不是原始帖子中给出的场景的可接受答案 - 尽管我接受接受的答案提供了纠正不良编码习惯的建议。【参考方案2】:您应该使用the like
keyword 对 char 字段进行部分匹配:
where days like '%1%'
编辑: VolkerK 和 Lukas Lalinsky 都建议使用 mysql 的 find_in_set
,这可能比 like
更好。但是,以下关于规范化数据库的建议仍然适用。
但是,您不应在单个数据库字段中存储多个值。相反,请考虑使用两个表:
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
)
(或者,应该很接近;我不完全确定您要完成什么或您的架构的其余部分是什么样的,所以这是一个最好的猜测)。
【讨论】:
谢谢。你对改变结构是正确的。我继续这样做。谢谢。 “所以这是一个最好的猜测”:另一个(希望是可行的)想法是使用dev.mysql.com/doc/refman/5.1/en/… 中描述的 NOT EXISTS 子查询,而不是x NOT IN (subquery)
%like% 会给出 11 来搜索 1,所以它并不真正适合,所以这个答案并不真正适用于原始问题。 theomega 的回答似乎更适用于 OP。【参考方案3】:
我想你想要的查询是:
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
但是您应该认真考虑规范化数据库,以便每天都有自己的行。
【讨论】:
【参考方案4】:如果我正确理解您的问题,您希望将 varchar 字段的内容视为逗号分隔的列表并测试该列表是否不包含某个值。为此,您需要 find_in_set(str, strlist) 函数。 但请记住,在这种情况下 MySQL 不能使用索引,并且您的查询将始终需要全表扫描。 可能最好不要将结构化数据(并对单个元素运行比较)存储在单个列中,而是使用其他响应中建议的另一个表和 JOIN。
【讨论】:
【参考方案5】:days 不包含字符串列表。它包含一个字符串。字符串“1,3,5”是否在 '1' 中的一个字符串内?显然答案是否定的。要么将 days 重构到不同的表中,要么准备进行更多的字符串操作
【讨论】:
以上是关于MySQL Select 语句,WHERE 'IN' 子句的主要内容,如果未能解决你的问题,请参考以下文章
准备好的语句,`WHERE .. IN(..)` 查询和排序 - 使用 MySQL
MySQL 2 SQL数据使用(检索排序过滤:SELECT/FROM/LIMIT/ORDER BY/DESC/WHERE/AND/OR/IN/NOT)