【问题标题】:Could someone help me clean this up? (Beginner, SQL)有人可以帮我清理一下吗? (初学者,SQL)
【发布时间】:2020-04-05 04:42:27
【问题描述】:

我正在hackerrank.com 上做练习(SQL 初学者练习),我相信你们中的许多人都很熟悉。

这是问题:

从 STATION 查询不以元音开头且不以元音结尾的 CITY 名称列表。您的结果不能包含重复项。

我的回答如下:

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, sql-server, oracle, ...?字符串函数是非常特定于数据库的。
  • 其实这个SQL查询还不错。在 Oracle 或 SQL Server 中,这可能会执行接近最佳查询,具体取决于 [station] 表的大小。
  • DISTINCT 不是函数,它是SELECT DISTINCT 的一部分!删除那些多余的括号,只需执行SELECT DISTINCT city FROM station... 即可使代码更清晰。
  • 您目前的方法有什么问题?还不够吗?

标签: mysql sql string substring where-clause


【解决方案1】:

这样的事情可能会有所帮助

SELECT DISTINCT city
FROM station
WHERE city NOT LIKE '[AEIOUaeiou]%[AEIOUaeiou]'

但是,在不知道您正在使用的确切 RDBMS 系统的情况下,此答案不是 %100 正确

【讨论】:

  • 这是特定于 SQL Server 的。
【解决方案2】:

在 MySQL 中,可以使用the REGEXP operator:

select distinct city
from station
where city not regexp '^[aeiou].*[aeiou]$'

如果您的列有区分大小写的排序规则,那么您可以在比较之前降低该值:

where lower(city) not regexp '^[aeiou].*[aeiou]$'

或者,如果您运行的是 MySQL 8.0,您可以使用 regexp_like() 并将匹配参数设置为 'i' 以使搜索不区分大小写:

where not regexp_like(city, '^[aeiou].*[aeiou]$', 'i')

【讨论】:

    【解决方案3】:

    @Dervis - 这可能会快一点。

    SELECT DISTINCT(city)
    FROM station
    WHERE UPPER(city) NOT LIKE '[AEIOU]%[AEIOU]'
    

    【讨论】:

    • 有了这个,你需要函数索引才能更快地工作。所以这对索引不友好
    • @DervişKayımbaşıoğlu 当然可以,但城市的数量肯定会相对较少。
    【解决方案4】:

    如果正则表达式是一个选项,则检查城市是否与以下模式不匹配:

    ^[aeiou]|[aeiou]$
    

    此模式匹配axxaaaa,即“城市以元音开头或结尾”。当您反转结果时,它变为“城市不以元音开头,也不以元音结尾”。参见德摩根定律。

    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
    

    【讨论】:

      猜你喜欢
      • 2023-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      相关资源
      最近更新 更多