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 都建议使用 mysqlfind_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 查询语句SELECT和数据条件过滤

mysql 中 in的用法

Where() in (select) H2

MySQL 2 SQL数据使用(检索排序过滤:SELECT/FROM/LIMIT/ORDER BY/DESC/WHERE/AND/OR/IN/NOT)

mysql 语句如何合并where字符串