我正在 hackerrank.com 上做练习(SQL初学者练习(,我相信你们中的许多人都很熟悉。
这是个问题:
从 STATION 查询不以元音开头且不以元音结尾的城市名称列表。您的结果不能包含重复项。
我的回答如下:
SELECT DISTINCT(city)
FROM station
WHERE city NOT LIKE 'A%'
AND city NOT LIKE 'E%'
AND city NOT LIKE 'I%'
AND city NOT LIKE 'O%'
AND city NOT LIKE 'U%'
AND city NOT LIKE '%a'
AND city NOT LIKE '%e'
AND city NOT LIKE '%i'
AND city NOT LIKE '%o'
AND city NOT LIKE '%u'
我知道这是一种荒谬的方法 - 你们能就如何缩短它提供建议吗?我只是目前对SQL没有足够的知识来使其更简洁。如果你能展示几种方法,那将非常有帮助。
在MySQL中,您可以使用REGEXP
运算符:
select distinct city
from station
where city not regexp '^[aeiou].*[aeiou]$'
如果您的列具有区分大小写的排序规则,则可以在比较之前降低该值:
where lower(city) not regexp '^[aeiou].*[aeiou]$'
或者,如果您运行的是 MySQL 8.0,则可以使用regexp_like()
并将 match 参数设置为'i'
以使搜索不区分大小写:
where not regexp_like(city, '^[aeiou].*[aeiou]$', 'i')
这样的事情可能会有所帮助
SELECT DISTINCT city
FROM station
WHERE city NOT LIKE '[AEIOUaeiou]%[AEIOUaeiou]'
但是,在不知道您正在使用的确切RDBMS系统的情况下,此答案不是%100正确的
如果正则表达式是一个选项,请检查城市是否与以下模式不匹配:
^[aeiou]|[aeiou]$
这种模式与ax
、xa
、aa
和a
相匹配,即"城市以元音开头或以元音结尾"。当你反转结果时,它就变成了"城市不以元音开头,也不以元音结尾"。参见德摩根定律。
MySQL实现:
SELECT DISTINCT city, NOT city REGEXP '^[aeiou]|[aeiou]$' AS result
FROM (
SELECT 'xx' AS city UNION
SELECT 'ax' UNION
SELECT 'xa' UNION
SELECT 'aa' UNION
SELECT 'x' UNION
SELECT 'a'
) AS station
-- returns 1 for xx and x, 0 for all others
@Dervis - 这可能会更快一些。
SELECT DISTINCT(city)
FROM station
WHERE UPPER(city) NOT LIKE '[AEIOU]%[AEIOU]'
查询不以元音开头或不以元音结尾的STATION
CITY
名称的列表。您的结果不能包含重复项。
这是针对MS SQL用户的
SELECT DISTINCT CITY FROM STATION WHERE CITY LIKE '[^aeiou]%' OR CITY LIKE '%[^aeiou]';