【问题标题】:SQL: Why LIKE doesn't work if character class [0-9] is used?SQL:如果使用字符类 [0-9],为什么 LIKE 不起作用?
【发布时间】:2013-12-13 08:30:27
【问题描述】:

假设我有一张桌子:

当前表:

title_id        title_name               title_qty
   1       A.I. Artificial Intelligence      2
   2       Batman Begins                    40
   3       2012                              7
   4       101 Dalmatians                   23
   5       Act of Valor                      1
   6       Batman                           50
   7       20 Million Miles to Earth       340

我想要输出:

期望的输出:

   title_id        title_name               title_qty  title_char
       4          101 Dalmatians                23          #
       7          20 Million Miles to Earth     340         #
       3                2012                    7           #
       1          A.I. Artificial Intelligence  2           A
       5          Act of Valor                  1           A
       6          Batman                        50          B
       2          Batman Begins                 40          B

根据我在 Stack Overflow 中读到的内容,检查字符是否为数字的最快方法是使用 LIKE '[0-9]%' 所以我想出了

查询:

SELECT *, CASE WHEN LEFT(title_name,1) LIKE '[0-9]%' THEN "#" ELSE LEFT(title_name,1) END as title_char FROM title ORDER BY title_name

输出:

title_id        title_name               title_qty  title_char
   4          101 Dalmatians                23          1
   7          20 Million Miles to Earth     340         2
   3                2012                    7           2
   1          A.I. Artificial Intelligence  2           A
   5          Act of Valor                  1           A
   6          Batman                        50          B
   2          Batman Begins                 40          B

如上所示,它根本不起作用。但是,如果我将 LIKE 更改为匹配单个数字,它会起作用:

SELECT *, CASE WHEN LEFT(title_name,1) LIKE '1%' THEN "#" ELSE LEFT(title_name,1) END as title_char FROM title ORDER BY title_name

title_id        title_name               title_qty  title_char
   4          101 Dalmatians                23          #
   7          20 Million Miles to Earth     340         2
   3                2012                    7           2
   1          A.I. Artificial Intelligence  2           A
   5          Act of Valor                  1           A
   6          Batman                        50          B
   2          Batman Begins                 40          B

我最初认为它不起作用,因为我的查询有点复杂,所以我做了一个简单的 SELECT WHERE。 LIKE 在 WHERE 之后添加。

没有输出(应该有三个):

SELECT * FROM title WHERE title_name LIKE '[0-9]%' ORDER BY title_name 

按预期工作:

SELECT * FROM title WHERE title_name LIKE '1%' ORDER BY title_name 

SELECT * FROM title WHERE title_name LIKE '2%' ORDER BY title_name

根据 SQL 文档,

字符类“[...]”匹配括号内的任何字符。 例如,“[abc]”匹配“a”、“b”或“c”。命名一个范围 字符,使用破折号。 “[a-z]” 匹配任何字母,而 “[0-9]” 匹配任何数字。

任何人都知道如果您使用字符类 [0-9] 它为什么不起作用?作为初学者,如果我错了,请纠正我。但我很好奇,如果我使用 LIKE '1%' 或任何数字,而 LIKE '[0-9]%' 不会给出任何结果,为什么它会起作用?文档说它应该匹配任何数字对吗?如果将其转换为整数是一项要求,那么它不应该适用于我的所有测试,对吧?因为我在进行 LIKE 比较之前没有投射它。

SQL 小提琴: http://sqlfiddle.com/#!2/492906/7

【问题讨论】:

  • 我编辑了问题...只是为了添加这个可以产生正确输出的查询,我使用了 RLIKE: SELECT *, CASE WHEN LEFT(title_name,1) RLIKE '[0-9 ]' THEN "#" ELSE LEFT(title_name,1) END as title_char FROM title ORDER BY title_name
  • The documentation you quote 大约是RLIKE,而不是LIKE,所以这对我来说似乎是正确的。在其他 SQL 方言中,[...]LIKE 接受,但(显然)在 MySQL 中不接受。

标签: mysql sql case sql-like


【解决方案1】:

The documentation 有点混乱。希望细心剪辑能让大家看得更清楚:

MySQL 提供标准的 SQL 模式匹配以及某种形式的模式匹配

[...]

SQL 模式匹配使您可以使用“_”匹配任何单个字符,使用“%”匹配任意数量的字符(包括零个字符)。在 MySQL 中,SQL 模式默认不区分大小写。此处显示了一些示例。使用 SQL 模式时不要使用=<>;请改用LIKENOT LIKE 比较运算符。

[...]

MySQL 提供的另一种模式匹配使用扩展的正则表达式。当您测试此类模式是否匹配时,请使用REGEXPNOT REGEXP 运算符(或RLIKENOT RLIKE,它们是同义词)。

[...]

字符类“[...]”匹配括号内的任何字符。例如,“[abc]”匹配“a”、“b”或“c”。要命名一系列字符,请使用破折号。 “[a-z]”匹配任何字母,而“[0-9]”匹配任何数字。

由于最后一句在“其他类型的模式匹配”下,它只适用于您已经找到的RLIKE,不适用于LIKE

【讨论】:

  • 您好,谢谢hvd!我很困惑。可能是因为我在 Stack Overflow 上发现了一篇推荐 LIKE[0-9] 来检查字符是否为数字的帖子,所以我认为它会起作用。谢谢,现在一切都清楚了!抱歉,如果我的问题如此简单和愚蠢,请告诉我是否应该删除它。无论如何,再次感谢我从这里学到了很多东西!
  • 一旦你知道原因,一切都变得简单而愚蠢。 :) 别担心,这是一个非常好的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-14
相关资源
最近更新 更多