【问题标题】:MySQL find words containing all letters at any placeMySQL在任何地方查找包含所有字母的单词
【发布时间】:2015-06-28 21:20:45
【问题描述】:

使用以下查询

SELECT * FROM words WHERE word REGEXP '(ord)'
  • 这将返回像 fordlordword 这样的词

如何包含这些字母出现但顺序不同的单词?

  • 例如adoredoorrandom

编辑

搞定了。

SELECT word, (
    IF(LOCATE('o', word) > 0, 1, 0) + 
    IF(LOCATE('r', word) > 0, 1, 0) +
    IF(LOCATE('z', word) > 0, 1, 0) +
    IF(LOCATE('a', word) > 0, 1, 0) +
    IF(LOCATE('d', word) > 0, 1, 0)) AS chars_present
from words
HAVING chars_present = 5

现在我将如何查询包含字母 r 的单词两次?

【问题讨论】:

  • [ord]{3}..... 但这会找到rod,但不会找到orsd,因为s 不是类的一部分,{3} 需要三个字符是连续的。
  • 你想用这个解决什么问题?似乎是一个非常奇怪的要求,可能有更好的方法可用。
  • 我对任何方法都很好...我的目标是从一个包含一些字母的表中以任意顺序检索单词。所有字母都必须出现。

标签: mysql regex


【解决方案1】:

在 mysql 中使用正则表达式要求所有三个字符都存在于任何位置会很丑陋,您可能会更好地使用以下内容:

SELECT (
    IF(LOCATE('o', words) > 0, 1, 0) + 
    IF(LOCATE('r', words) > 0, 1, 0) +
    IF(LOCATE('d', words) > 0, 1, 0)) AS chars_present
...
HAVING chars_present = 3

【讨论】:

  • 您的询问让我有点不知所措。我的表是words,列是word。完整的语法是什么?
  • 不,这不是复杂的语法,只是显示了关键部分——检查每个特定字符是否存在,并且只允许所有三个都存在的记录通过。下面 ricKJames 的版本更容易理解,但我的版本允许您对每个字符的数量设置限制(例如 3 o、2 d 和 1 r)。
  • 好的,我想我掌握了语法。你如何设置限制?我试过IF(LOCATE('r', words) > 0, 2, 0),但这似乎不起作用。
  • 你将单独的 if() 语句分成它们自己的别名,然后 having r_count = X, o_count=Z, etc..
  • 你介意用一个例子更新你的答案吗?
【解决方案2】:

只需对每个字母重复规则即可。

SELECT * FROM words WHERE word REGEXP 'o' AND word REGEXP 'r' AND word REGEXP 'd'

规则出现的顺序无关紧要。

【讨论】:

  • + 是不必要的。)
【解决方案3】:

这可能是最快的:

SELECT *
    FROM words
    WHERE LOCATE('o', word)
      AND LOCATE('r', word)
      AND LOCATE('d', word);

mysql> SELECT city, state FROM us
      WHERE locate('o', city) AND locate('r', city) AND locate('d', city)
      LIMIT 11;
+---------------+-------+
| city          | state |
+---------------+-------+
| Irondale      | AL    |
| Oxford        | AL    |
| El Dorado     | AR    |
| Paragould     | AR    |
| Sherwood      | AR    |
| Goodyear      | AZ    |
| Safford       | AZ    |
| Alondra Park  | CA    |
| Anderson      | CA    |
| Arroyo Grande | CA    |
| Atascadero    | CA    |
+---------------+-------+
11 rows in set (0.00 sec)

如果您需要两个r,则对它们的测试将是word REGEXP 'r.*r'

mysql> SELECT city, state FROM us
    ->           WHERE locate('o', city) AND city REGEXP 'r.*r' AND locate('d', city)
    ->           LIMIT 5;
+--------------------+-------+
| city               | state |
+--------------------+-------+
| Alondra Park       | CA    |
| Arroyo Grande      | CA    |
| Corte Madera       | CA    |
| Desert Hot Springs | CA    |
| Garden Grove       | CA    |
+--------------------+-------+

【讨论】:

  • +1 表示完整查询。如果我想输入两次相同的字母怎么办?例如,包含o, r, r, d的单词。
  • 谢谢。 locate 应该比 REGEXP 快吗?
  • 我没有任何基准测试,但我希望locateregexp 快很多。但是,如果没有regexp,我想不出一种方法来轻松快速地完成 2r。真正的性能损失是必须读取每一行(没有索引是有帮助的)并多次扫描列。
  • 另外,LIKE 可能更快:city LIKE '%o%'
猜你喜欢
  • 2014-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多