2016-09-13 77 views
1

如果我有4條地址線如下:MySQL的ORDER BY忽略NUMERICS

1 West Road 
65 Brown Street 
800 Albian Road 
Holland House 

我想訂購他們,卻忽略在前面的數字,所以他們會在這個順序結束:

800 Albian Road 
65 Brown Street 
Holland House 
1 West Road 

這可能嗎?

+0

如果你使用mariadb,'SELECT * FROM address ORDER BY REGEX_REPLACE(line1,'/^[0-9] + /','');'也許可以。可悲的是不在MySQL 5.6中:http://www.sqlfiddle.com/#!9/737629/3 – jedifans

+0

可能重複的[MYSQL選擇一段字符串並按該段順序](http://stackoverflow.com/問題/ 6475936/mysql-select-a-piece-of-a-string-and-by-that-piece) – Tushar

+0

它不那麼容易。看看這個[一個論壇](http://www.futurequest.net/forums/archive/index.php/t-20869.html)它不像他們抨擊了一個答案 – Drew

回答

2

我建議以下功能。它在底部進行測試。

DROP FUNCTION IF EXISTS noNumAtFront; 
DELIMITER $$ 
CREATE FUNCTION noNumAtFront(s VARCHAR(100)) 
    RETURNS VARCHAR(100) 
BEGIN 
    DECLARE i,iSize INT; 
    DECLARE bContinue BOOL DEFAULT TRUE; 
    DECLARE ls VARCHAR(100); -- local s 
    DECLARE retString VARCHAR(100); 
    SET ls=LTRIM(s); 
    SET iSize=LENGTH(ls); 
    SET i=1; 
    WHILE (i<=iSize AND bContinue) DO 
     IF ASCII(SUBSTRING(ls,i,1)) NOT BETWEEN 48 AND 57 THEN 
      SET bContinue=FALSE; 
     ELSE 
      SET i=i+1; 
     END IF; 
    END WHILE; 
    SET retString=RIGHT(ls,iSize-i+1); 
    -- RETURN CONCAT('i= ',i); 
    RETURN(TRIM(retString)); 
END;$$ 
DELIMITER ; 

測試

SELECT noNumAtFront('canal ave.'); 
SELECT noNumAtFront('8 fff'); 
SELECT noNumAtFront(' PO Box 1'); 
SELECT noNumAtFront(''); 
SELECT noNumAtFront('15151515'); 
SELECT noNumAtFront('5'); 

更好的測試:

CREATE TABLE addr 
( ID int AUTO_INCREMENT PRIMARY KEY, 
    address1 VARCHAR(100) NOT NULL 
); 
INSERT addr (address1) VALUES ('canal ave.'),('123 Main St'),('3 abc lane'); 

select addr1 as address 
FROM 
( select noNumAtFront(address1) as addr1 FROM addr 
) d 
ORDER BY address; 
+------------+ 
| address | 
+------------+ 
| abc lane | 
| canal ave. | 
| Main St | 
+------------+ 

d是一個派生表名。每個派生表都需要一個名稱或出錯。像這樣的包裝需要清理函數輸出到名稱中,然後稍後(在外部查詢中)對其進行排序。

此版本2編輯在給出的函數結尾處具有TRIM。