代码之家  ›  专栏  ›  技术社区  ›  Dodinas

mysql select语句,其中'in'子句

  •  7
  • Dodinas  · 技术社区  · 16 年前

    我的表中当前有以下行:

             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”中)。

    但是,我没有发现这是事实。尽管 一天=“1” ,它仍然返回该行。

    唯一不返回行的方法是 $day= "1,3,5." 然而,我认为in()子句将接受我的变量的任何一部分,并将其应用于该列。

    对我在这里做错了什么有什么见解吗?谢谢。

    5 回复  |  直到 16 年前
        1
  •  11
  •   James McNellis    16 年前

    你应该使用 the like keyword 要对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
        )
    

    (或者,应该很接近;我不是 确切地 当然,您要完成的是什么,或者模式的其他部分是什么样子的,所以这是一个最好的猜测)。

        2
  •  13
  •   theomega    16 年前

    删除in语句中的引号。语法是:

    ... WHERE column IN (1,2,3) 
    

    而且不像你用的那样

    ... WHERE column IN ('1,2,3')
    

    也看到 documentation 在中,有更多的例子。

        3
  •  5
  •   LukáÅ¡ Lalinský    16 年前

    我想你需要的是:

    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
  •  2
  •   VolkerK    16 年前

    如果我正确理解您的问题,您希望将varchar字段的内容视为逗号分隔的列表,并测试此列表是否不包含某个值。为此你需要 find_in_set(str, strlist) 功能。
    但请记住,在这种情况下,MySQL不能使用索引,您的查询总是需要一个完整的表扫描。它 可以 最好不要在单个列中存储结构化数据(并在单个元素上运行比较),而是像其他响应中建议的那样使用另一个表和联接。

        5
  •  0
  •   Yuliy    16 年前

    天不包含字符串列表。它只有一根绳子。字符串“1,3,5”是否位于'1'中的某个字符串内?显然,答案是否定的。要么将天数重构为另一个表,要么准备进行更多的字符串操作。