如何从station表筛选首尾非元音的多词城市名称?
解决多词城市名的首尾非元音匹配问题
原SQL的问题很明确:
- 正则
^[^AEIOU][^aeiou]$限定了字符串只能是两个字符,完全无法匹配Yazoo City这类多词或长字符的城市名 - 大小写处理逻辑混乱,首字符只排除大写元音,尾字符只排除小写元音,会漏掉多种大小写组合的不匹配场景
下面给出几种通用的正确实现方式,适配不同数据库:
1. 正则表达式方式(推荐,简洁)
核心逻辑:匹配字符串首字符不是元音、字符串尾字符不是元音,中间允许任意字符(包括空格、多词)。
Oracle/DB2
SELECT DISTINCT city FROM station WHERE REGEXP_LIKE(city, '^[^AEIOUaeiou].*[^AEIOUaeiou]$', 'i') ORDER BY city;
'i'参数表示忽略大小写,也可以去掉该参数,保持正则里的大小写元音全量枚举.*表示中间可以是任意长度的任意字符,完美支持多词城市名
MySQL/MariaDB
SELECT DISTINCT city FROM station WHERE city REGEXP '^[^aeiou].*[^aeiou]$' ORDER BY city;
MySQL的REGEXP默认不区分大小写(依赖数据库排序规则),如果需要严格控制可以添加BINARY关键字。
PostgreSQL
SELECT DISTINCT city FROM station WHERE city ~* '^[^aeiou].*[^aeiou]$' ORDER BY city;
~*是PostgreSQL的忽略大小写正则匹配操作符。
2. 非正则方式(兼容所有数据库)
如果你的数据库对正则支持有限,或者更习惯用字符串函数实现:
SELECT DISTINCT city FROM station WHERE UPPER(SUBSTR(city, 1, 1)) NOT IN ('A', 'E', 'I', 'O', 'U') AND UPPER(SUBSTR(city, LENGTH(city), 1)) NOT IN ('A', 'E', 'I', 'O', 'U') ORDER BY city;
- SQL Server需替换为
LEFT(city, 1)和RIGHT(city, 1)替代SUBSTR - 如果城市名存在首尾空格,建议先用
TRIM(city)处理后再取首尾字符,避免误判
内容的提问来源于stack exchange,提问作者Minh Nguyễn
相关产品推荐
相关产品推荐

