《SQL必知必会(第4版)》第6课 用通配符进行过滤

6.1.3 方括号([])通配符

方括号([])通配符用来指定一个字符集,它必须匹配指定位置(通配符的位置)的一个字符。

……

此通配符可以用前缀字符^(脱字号)来否定。例如,下面的查询匹配不以 J 或 M 起头的任意联系人名:

SELECT cust_contact
FROM Customers
WHERE cust_contact LIKE '[^JM]%'
ORDER BY cust_contact;

当然,也可以使用 NOT 操作符得出相同的结果。^ 的唯一优点是在使用多个 WHERE 子句时可以简化语法:

SELECT cust_contact
FROM Customers
WHERE NOT cust_contact LIKE '[JM]%'
ORDER BY cust_contact;

该小节第一句话“它必须匹配指定位置的一个字符”非常正确。

然后作者说:'[^JM]%' 匹配不以 JM 起头的任意联系人,这就不对了。正确的说法应该是:'[^JM]%' 匹配以 JM 之外的任意字符起头的联系人。因为 '[^JM]%' 要求至少有一个字符,它无法匹配空字符串 '' ,而“不以 JM 起头的任意联系人名”理论上可以包括空字符串的情形。

作者接着说:当然,也可以使用 NOT 操作符得出相同的结果。这也不对。结果并不严格相同:LIKE '[^JM]%' 不能匹配空字符串,NOT LIKE '[JM]%' 能。

正则表达式

正则表达式也有同样的方括号语法(我猜 M$ SQL 的方括号通配符语法就是从与正则表达式学来的)。注意:无论是否有脱字号 ^[...] 必须匹配且只能匹配一个字符,不能是零个,也不能多于一个。[^...] 中的 ^ 是否定脱字号之后的 ... ,而不是否定整个方括号 [...] 。正则表达式的初学者经常在这个地方犯错误,应引以为戒。