【问题标题】:omit results starting with certain character省略以特定字符开头的结果
【发布时间】:2015-06-19 22:14:31
【问题描述】:

我正在尝试使用 mysql 从姓氏不以 z 或 Z 开头的表中检索名称列表。我尝试将 substring 与 instr 结合来完成此操作。尝试如下:

    SELECT DISTINCT SQL_CALC_FOUND_ROWS CONCAT(FName," ",SName)
    FROM Names  
    WHERE SUBSTRING(
                    CONCAT(FName, ' ' ,SName),
                    INSTR(CONCAT(FName, ' ' ,SName), ' ') +1,
                    1) 
          <> 'z' 
    OR SUBSTRING(
                  CONCAT(FName, ' ' ,SName), 
                  INSTR(CONCAT(FName, ' ' ,SName), ' ') +1, 
                  1)
          <> 'Z' 
    ORDER BY SName

我的尝试是以 z 作为姓氏的第一个字母返回结果。谁能解释为什么?或者如果有更好的方法来实现这一点

【问题讨论】:

    标签: mysql sql database substring


    【解决方案1】:

    这可以用LIKE大大缩短:

    SELECT DISTINCT SQL_CALC_FOUND_ROWS CONCAT(FName," ",SName)
    FROM Names  
    WHERE FName NOT LIKE 'z%' AND FName NOT LIKE 'Z%';
    

    IIRC LIKE 自 MySQL v5.6.x 起区分大小写

    我不会这样写

    ...WHERE LOWER(FName) NOT LIKE 'z%';
    

    因为在列上应用函数会阻止 MySQL 使用列上的索引(如果存在的话)。

    【讨论】:

    • 这很容易谢谢。我现在看到我犯的一个关键错误是使用 OR 而不是 AND!不知道我在想什么
    【解决方案2】:
    SELECT DISTINCT SQL_CALC_FOUND_ROWS CONCAT(FName," ",SName)
    FROM Names
    WHERE FName REGEXP '^[^z]';
    

    【讨论】:

    • 我现在没有任何资源来支持这一点,但如果你可以使用like 而不是regexp,那么如果你关心性能,你绝对应该使用like
    • 是的,你是对的!正则表达式的性能比同类更差,但它非常方便!)而且没有提到任何关于性能的问题......当我写这个答案时,我看到了你的答案,并决定写另一个选项)
    猜你喜欢
    • 1970-01-01
    • 2010-10-11
    • 2011-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-08
    • 1970-01-01
    相关资源
    最近更新 更多