【问题标题】:compare 2 strings seprate by comma in sql query在sql查询中比较用逗号分隔的2个字符串
【发布时间】:2014-05-15 01:55:45
【问题描述】:

我有一张这样的表格

category
--------------
20,14,13,16,19

我有这个字符串:

20,16,9,5

我想查找具有此类别的产品

在mysql查询中。

有人有想法吗?

【问题讨论】:

  • 为此使用 WHERE cat IN()
  • 第一个建议:正确规范您的数据库。第二个建议:FIND_IN_SET()
  • 我试过这两个建议它没有得到所有的记录
  • 显示您正在构建的查询,而不是期望我们用最少的信息猜测,然后简单地告诉我们我们的猜测不起作用

标签: php mysql sql find-in-set


【解决方案1】:

我们可以匹配逗号分隔的值,

这是一个 Mysql 查询

SELECT tens.d*10 + ones.d AS n
FROM (SELECT 0 AS d UNION ALL
SELECT 1 AS d UNION ALL
SELECT 2 AS d UNION ALL
SELECT 3 AS d UNION ALL
SELECT 4 AS d UNION ALL
SELECT 5 AS d UNION ALL
SELECT 6 AS d UNION ALL
SELECT 7 AS d UNION ALL
SELECT 8 AS d UNION ALL
SELECT 9 AS d) AS tens
INNER JOIN
(SELECT 0 AS d UNION ALL
SELECT 1 AS d UNION ALL
SELECT 2 AS d UNION ALL
SELECT 3 AS d UNION ALL
SELECT 4 AS d UNION ALL
SELECT 5 AS d UNION ALL
SELECT 6 AS d UNION ALL
SELECT 7 AS d UNION ALL
SELECT 8 AS d UNION ALL
SELECT 9 AS d) AS ones
WHERE (tens.d*10 + ones.d) IN (20,14,13,16,19)
AND (tens.d*10 + ones.d) IN ( 20,16,9,5 )
ORDER BY n

【讨论】:

    【解决方案2】:
    $myString = '20,16,9,5';
    
    $sets = array();
    foreach(explode(',', $myString) as $individualValue) {
        $sets[] = 'FIND_IN_SET(' . $individualValue. ', category) > 0';
    }
    $whereClause = implode(' OR ', $sets);
    
    $myQuery = 'SELECT * FROM mytable';
    if ($whereClause > '') {
        $myQuery .= ' WHERE ' . $whereClause;
    }
    

    【讨论】:

    • 你的代码中有一个小错误:在 foreach 循环中你应该写$sets[] = 。除此之外,我认为这是一个不错的解决方案。
    • @Typoheads - 修复感谢;但这是一个可怕的解决方案……最好的解决方案是规范化数据库;下一个最佳解决方案是使用 PDO 或 MySQLi 和准备好的语句/绑定变量的解决方案......但我猜海报将使用 MySQL 扩展......这个快速/肮脏的建议甚至不测试字符串值在 $myString 而不是简单的数字中
    • OP 提出了一个简单的问题并得到了直接的答案。我同意,在谈论代码质量和软件/数据库设计时,这不是一个好的解决方案。但是这里的答案不应该是完整的“如何编写完美的软件”指南,它应该回答所提出的问题。当然,您可以尝试告诉任何人使用准备好的语句、PDO、mysqli 并确保软件安全,但有时专注于回答问题就足够了。 :-)
    【解决方案3】:

    这取决于你的桌子如何,但如果你的桌子是这样的:
    id_product | id_category |姓名 |其他领域
    尝试这种查询: 选择

    $category_array='20,16,9,5';
    $query = "SELECT * FROM MYTABLE WHERE id_category IN (" . $category_array . ")";

    【讨论】:

      【解决方案4】:

      为了完成这里的一组答案,还有一个应该带有健康警告的答案。

      这假定对问题的解释与:QuentinJadeau 完全相同。

      也就是说,输入由一个字符串组成,该字符串包含一个逗号分隔的“类别”列表。

      我已经测试过了。我试图设置一个“SQLFiddle”,但排在第二位。 ;-/ 我可以发布结果。

      遗憾的是,它按预期工作,类似于提供的答案“MarkBaker”。唯一不同的是,这是数据库中的一个函数,而不是他做的方式。这是第二种最佳方式,因为当您可以动态生成完整的 SQL 查询时,您可以做更多的事情。 ;-/

      我回答这个问题是因为我想写一些“有用”的“mysql”函数。

      FIND_IN_COMMA_LIST 函数

      它是一个“mysql”函数,它接受一个逗号分隔的源列表,将其拆分并将每个项目与目标逗号分隔列表进行比较,使用 mysql 的“find_in_set”函数。它返回找到的第一个匹配项。

      已测试:服务器版本:Mysql 5.5.16

      下面的示例将返回“x”

      SELECT find_in_comma_list('1,2,x', 'a,b,c,9,x')
      
      DROP FUNCTION IF EXISTS FIND_IN_COMMA_LIST;
      DELIMITER $$
      /*
        needles  => comma separated list of items
        haystack => comma separated list of items
      
        returns first item in 'needles' list that is found in the 'haystack' list
      */
      CREATE
          FUNCTION `testmysql`.`FIND_IN_COMMA_LIST` (needles VARCHAR(128), haystack VARCHAR(255))
          RETURNS VARCHAR(255)
          BEGIN
            DECLARE which INT DEFAULT 0;
            DECLARE result VARCHAR(255) DEFAULT '';
            simple_loop: LOOP
               SET which = which + 1;
               SET result = SPLIT_STR(needles, ',', which);
               IF result = '' THEN
                  LEAVE simple_loop;
               END IF;
               IF FIND_IN_SET(result, haystack) != 0 THEN
                  LEAVE simple_loop;
               END IF;         
             END LOOP simple_loop;
           RETURN result; 
          END$$
      
      DELIMITER ;
      

      它依赖于我在别处找到的另一个功能。

      DROP FUNCTION IF EXISTS SPLIT_STR;
      DELIMITER $$
      
      CREATE
          /*[DEFINER = { user | CURRENT_USER }]*/
          FUNCTION `testmysql`.`SPLIT_STR`(haystack VARCHAR(255), delim VARCHAR(16), which INTEGER)
          RETURNS VARCHAR(255)
          BEGIN
            RETURN REPLACE(
                           SUBSTRING(SUBSTRING_INDEX(haystack, delim, which),
                                     LENGTH(SUBSTRING_INDEX(haystack, delim, which - 1)) + 1),
             delim, '');
          END$$
      
      DELIMITER ;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-25
        • 1970-01-01
        • 2017-12-24
        • 2020-03-08
        • 2017-09-09
        相关资源
        最近更新 更多