2015-04-14 41 views
2

我試圖從一張表中找出姓名列表,其中姓氏不是以z或z開始使用mysql。我嘗試將子字符串與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作爲姓氏的第一個字母。誰能解釋爲什麼?或者,如果有更好的方法來實現這一

回答

2

這可以用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使用列上的索引(如果存在)。

+0

這很容易謝謝。我現在看到我犯的一個嚴重錯誤是使用OR而不是AND!不知道我在想什麼 – user2363025

1
SELECT DISTINCT SQL_CALC_FOUND_ROWS CONCAT(FName," ",SName) 
FROM Names 
WHERE FName REGEXP '^[^z]'; 
+0

我現在沒有手頭來支持這個,但如果你可以使用'like'而不是'regexp',那麼你應該使用'like',如果你關心性能。 – fancyPants

+0

是的,你是對的!正則表達式比類似的表現更糟糕,但它非常方便!)而且沒有提及性能......當我寫這個答案時,我看到了你的答案,並決定寫另一個選項) –

相關問題