【问题标题】:MySQL list IN listMySQL 列表 IN 列表
【发布时间】:2012-01-11 05:36:34
【问题描述】:

我目前将用户的输入存储在逗号分隔的列表中,如下所示:

Userid | Options
1      |  1,2,5

用户以数组形式勾选一组选项,然后用逗号将其连接起来

1,2,5

然后 MySQL 正在尝试查找在不同字段名称(尽管是同一个表)上勾选了部分或全部相同选项的其他用户。

目前我这样做:

WHERE `choices` IN ('.$row['myoptions'].')

所以这可能是这样的:

WHERE 1,2,5,8 IN (1,4,6)

这将返回 true,因为至少有一个值匹配,对吗?还是我弄糊涂了..

【问题讨论】:

  • Options 的数据类型是什么?
  • choices 也有逗号分隔值或单个值???
  • @Starz 数据类型显然是 varchar
  • 您希望匹配精确的选项集或您在此处所做的任何选项。
  • 我认为它会返回 True,当然是一个元组左右。

标签: mysql


【解决方案1】:

我认为这不会返回 true。

WHERE CHOICES IN ()

当你这样做时,它会将完整的 choices 值与 IN 中的单个项目进行比较

你可能想看看MySQL的find_in_Set函数

WHERE find_in_set(optionNumber1, choices) > 0 
OR find_in_set(optionNumber2, choices) > 0
OR find_in_set(optionNumber3, choices) > 0

你必须在你正在使用的编程语言中循环查询

【讨论】:

  • 这就是为什么我很困惑,因为我一直在向我建议这两个功能 =/
  • 这很简单,无需混淆,IN() 会将左侧的完整字符串与右侧的逗号分隔字符串进行比较。您可能想使用 find_in_set 函数,但这样您将不得不一次选择一个选项
【解决方案2】:

我认为你不会感到困惑。你是绝对正确的,这将返回一些东西(一个元组或一个以上的元组),这当然是一个 True 值。所以继续....

【讨论】:

  • 那么,如果我为用户提供“精确”匹配的选项,我该怎么办?
【解决方案3】:

你可能走错了路。

如果选项列类型为SET,则函数 FIND_IN_SET 可能会有所帮助。

例子:

SELECT * FROM yourtabe WHERE FIND_IN_SET('2', Options);

但是,它只会让您一次比较一个字符串,在上面的示例中,它比较行中是否存在 2。如果您必须比较多个值,则无法使用 FIND_IN_SET 来完成。

但是,在您的情况下,LIKE 子句可能对您有用。

可能是这样的

SELECT * FROM yourtable WHERE Options LIKE '%2,3%';

现在这将在列中的任意位置搜索 2,3 值,并给出结果。但这也带来了另一个复杂性,只有当2,3 并排存在时才会给出结果,如果列有2,1,32,4,5,3 甚至3,2 它不会列出这些记录。

现在来回答你的问题

`WHERE `choices` IN (1,4,6)`, 

将转换为

WHERE `choices` = '1' OR `choices` = '4' OR `choices` = '6'

所以它会返回false

为什么?

因为您的列不仅包含 1 或 4 或 6,还包含 1,2,5 作为一个字符串。所以上面所有的比较都返回false

【讨论】:

  • 所以我的 IN 函数是最好的选择,因为它将比较多个字段?
  • 天啊,我做错了,它会返回 false。我会解释的
  • 所以如果用户尝试使用 IN 搜索多个值,每次都会返回 false ?
  • 这是您的数据类型最重要的地方。作为 varchar,无论您比较单个数字还是多个仅与列数据完全匹配的数据都将返回 true,否则将返回 false。如果您想要单一比较,那么SET 是您的最佳选择,请参阅我提供的示例。
  • 您可以查看this之前提出的问题以获取更多信息
【解决方案4】:

我不知道choice列在哪个表中,但你试过这种方式吗

SELECT * FROM t1 WHERE `choices` > ANY (SELECT options FROM t2);

Reference

【讨论】:

  • 我的查询 WHERE 子句在编译后看起来像这样:gender IN (2) AND orientation IN (1,2) AND selections IN (1,2,4,5,7,8) The numbers括号中来自 PHP 中的 $vars,它是从有关当前登录用户的行中加载的,而该用户恰好来自之前加载的同一个表。
【解决方案5】:

刚刚遇到同样的问题。使用RLIKE解决了它:

$options_in_row = array_filter(explode(',',$row['myoptions'])); // convert the csv to array of numbers. use array_filter because empty values will generate a regex that always find something.
$options_rx = implode('|', array_map(function ($x)
        {
            return "\b$x\b"; // adding \b to avoid partial number hits, such as '2' inside '123,234'
        }, $options_in_row));
// $options_rx is something like '\b123\b|\b234\b'
$sql = '.... WHERE `choices` RLIKE "'.$options_rx.'"';

考虑到此代码假定数字为 csv。如果您的情况不同,则必须添加转义。

【讨论】:

    猜你喜欢
    • 2018-08-30
    • 2017-08-27
    • 2012-12-06
    • 1970-01-01
    • 2014-09-17
    • 2012-10-23
    • 2012-08-11
    • 2013-07-24
    • 1970-01-01
    相关资源
    最近更新 更多