繁体   English   中英

MySQL 多点查询的正则表达式解决方案

[英]MySQL Regexp Solution for Multi-Like Query

我希望以下内容有意义。 我的查询应该返回size列中的字符串值(+ 或 - 5)不存在于其相应title列中的所有行。

桌子:

 --------------
| size  | title|
 --------------
| 50    | 50ml |
| 75    | 75ml |
| 75    | 50ml |
| 100   | 97ml |
 --------------

Controller:

    $data = [
        'find_all_sizes' => $model
            ->where('CONCAT(brand, " ", title) NOT LIKE CONCAT("%", size - 5, "%")')
            ->where('CONCAT(brand, " ", title) NOT LIKE CONCAT("%", size - 4, "%")')
            ->where('CONCAT(brand, " ", title) NOT LIKE CONCAT("%", size - 3, "%")')
            ->where('CONCAT(brand, " ", title) NOT LIKE CONCAT("%", size - 2, "%")')
            ->where('CONCAT(brand, " ", title) NOT LIKE CONCAT("%", size - 1, "%")')
            ->where('CONCAT(brand, " ", title) NOT LIKE CONCAT("%", size, "%")')
            ->where('CONCAT(brand, " ", title) NOT LIKE CONCAT("%", size + 1, "%")')
            ->where('CONCAT(brand, " ", title) NOT LIKE CONCAT("%", size + 2, "%")')
            ->where('CONCAT(brand, " ", title) NOT LIKE CONCAT("%", size + 3, "%")')
            ->where('CONCAT(brand, " ", title) NOT LIKE CONCAT("%", size + 4, "%")')
            ->where('CONCAT(brand, " ", title) NOT LIKE CONCAT("%", size + 5, "%")')
            ->groupBy('id')
            ->findAll()
    ];

这很好用 - 但我猜可能有更好的方法通过使用正则表达式来做到这一点,这是我真正需要帮助的地方。

你可以试试:

$data = [
        'find_all_sizes' => $model
            ->where("abs(size - cast(replace(title, 'ml', '') as signed)) < 5")
            ->groupBy('id')
            ->findAll()
    ];

在 SQL 中,假设ml是标题中唯一不是数字的文本,则 select * 查询将如下所示:

select * from t
where abs(size - cast(replace(title, 'ml', '') as signed)) < 5;

+------+-------+
| size | title |
+------+-------+
|   50 | 50ml  |
|   75 | 75ml  |
|  100 | 97ml  |
+------+-------+

如果您的标题也可以包含其他字符串,您可以创建一个 function,如下所示: How do you extract a numeric value from a string in a MySQL query? 然后运行

select * from t
where abs(size - cast(digits(title) as signed)) < 5;

你可能会侥幸逃脱

select * from t
where abs(size - cast(title as signed)) < 5;

或者

$data = [
        'find_all_sizes' => $model
            ->where("abs(size - cast(title as signed)) < 5")
            ->groupBy('id')
            ->findAll()
    ];

另一个简短的答案,但有点笨拙:

WHERE 0+title BETWEEN size-5 AND size+5

在 MySQL 中,当在数字上下文中使用字符串时,使用前导数字并忽略 rest。 (没有前导数字的字符串被视为零。)

(抱歉,不需要 REGEXP。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM