我有一个带有地址列的mysql表。 现在我需要分别选择街道名称和号码。
Address
Wallstreet 20
New Yorkavenue 30
New London Street 40
需要:
Street: Number:
Wallstreet 20
New Yorkavenue 30
New London Street 40
有什么想法吗? 提前谢谢!
答案 0 :(得分:4)
如果您认为该数字是最后的“单词”并用空格分隔:
select replace(address, substring_index(address, ' ', -1), '') as street,
substring_index(address, ' ', -1) as number
我碰巧认为这两个假设是非常大的假设,这意味着这可能不适用于所有行。
答案 1 :(得分:2)
对于Mysql,如果数字仅在地址编号中且地址没有数字,您可以创建MYSQL SUBSTRING_INDEX来分隔字段。
实施例
SELECT
REPLACE(address, SUBSTRING_INDEX(address, ' ', -1), '') as ADDRESS,
SUBSTRING_INDEX(address, ' ', -1) as NUMBER
FROM
ADDRESSES
它在性能方面不是一个非常好的方法,并且可能用其他方式完成,但如果模式总是像示例那样可以工作
在客户端以获取数据的语言在性能上也可能更好。
答案 2 :(得分:2)
您可以使用一些字符串函数,例如SUBSTRING_INDEX和LEFT。
获取数字很简单:
SELECT
SUBSTRING_INDEX(Street, ' ', -1)
(是的,它实际上不是一个数字,但我想它是最后一个空格后字符串的最后一部分,它也可以是20 / C的字符串。)
获取街道名称有点棘手:
SELECT
LEFT(Street,
CHAR_LENGTH(Street)
-CHAR_LENGTH(SUBSTRING_INDEX(Street, ' ', -1))
-1
) AS street_name,
SUBSTRING_INDEX(Street, ' ', -1) AS street_number
FROM
tablename
答案 3 :(得分:0)
我可能会迟到一些,但问题仍然是同一天: - )
问题是,如何从地址字符串中拆分/选择街道名称(Straßenname)和数字(Hausnummer)?
因此我创建了一个功能,以实现德国DIN 5008:
DROP FUNCTION IF EXISTS HAUSNUMMER_DIN_5008;
delimiter //
CREATE DEFINER=`vlw`@`%` FUNCTION `HAUSNUMMER_DIN_5008`(
oldStreet VARCHAR(255), formating BOOL
) RETURNS varchar(16) CHARSET utf8
BEGIN
SET @oldString := oldStreet;
SET @newString := "";
tokenLoop: LOOP
END LOOP tokenLoop;
-- are there no figures at the beginning of street name?
IF NOT @oldString REGEXP '^[1-9]' THEN
-- must be a word, to jump over
SET @splitPoint := LOCATE(" ", @oldString);
SET @oldString := SUBSTRING(@oldString, @splitPoint+1);
ELSE
-- Okay, we found the first figure
-- Are there any chars inside the string including "."
IF @oldString REGEXP '[a-z,A-Z,.,--,/," "]' THEN
-- Are there any char directly behind a figure
IF @oldString REGEXP '[0-9][a-z,A-Z,.,--,/," "]' THEN
-- now we have to check step by step
SET @i := 1;
tokenPos: LOOP
-- jump over the first figures
IF NOT SUBSTRING(@oldString, @i, 1) REGEXP '[0-9]' THEN
-- this is the first non figure
IF formating THEN
IF SUBSTRING(@oldString, @i, 1) REGEXP '[a-z,A-Z]' THEN
-- If a char is directly written after figures, then add a blank between
SET @oldString := CONCAT(SUBSTRING(@oldString,1,@i-1)," ",SUBSTRING(@oldString,@i));
LEAVE tokenPos;
ELSE
IF SUBSTRING(@oldString, @i, 1) = "." THEN
-- this must be part of the street name, so we will loop some what
LEAVE tokenPos;
END IF;
-- SET @newString := concat(">xx>",REPLACE(@oldString," ",""));
SET @newString := REPLACE(@oldString," ","");
LEAVE tokenLoop;
END IF;
LEAVE tokenPos;
ELSE
IF SUBSTRING(@oldString, @i, 1) = "." THEN
-- this must be part of the street name, so we will loop some what
LEAVE tokenPos;
ELSE
-- the street number is found
SET @newString := @oldString;
LEAVE tokenLoop;
END IF;
END IF;
END IF;
SET @i := @i+1;
END LOOP tokenPos;
END IF;
SET @splitPoint := LOCATE(" ", @oldString);
IF SUBSTRING(@oldString, @splitPoint+1) REGEXP '[1-9]' THEN
-- we have to split one more word
SET @oldString := SUBSTRING(@oldString, @splitPoint+1);
ELSE
SET @newString := @oldString;
LEAVE tokenLoop;
END IF;
ELSE
IF formating AND @oldString REGEXP '[//][1-9]' THEN
SET @i := LOCATE(@oldString,"//")+4;
SET @oldString := CONCAT(SUBSTRING(@oldString,1,@i)," ",SUBSTRING(@oldString,@i+1));
ELSEIF formating THEN
SET @oldString := REPLACE(@oldString," ","");
END IF;
SET @newString := @oldString;
LEAVE tokenLoop;
END IF;
END IF;
RETURN @newString;
END //
delimiter ;
还有一个额外的BOOLEAN参数,用于根据DIN 5008重新格式化地址的编号部分。但重新格式化部分尚未最终完成。 现在我们可以用一些例子来测试它:
select HAUSNUMMER_DIN_5008("Mörikestr. 28/3",TRUE);
select HAUSNUMMER_DIN_5008("Nettelbeckstraße 6 a",TRUE);
select HAUSNUMMER_DIN_5008("Auf dem Brande 19a",TRUE); ==>> "19 a"
select HAUSNUMMER_DIN_5008("Auf dem Brande 19a",FALSE); ==>> "19a"
select HAUSNUMMER_DIN_5008("Anger 1-3",TRUE);
select HAUSNUMMER_DIN_5008("Straße des 17. Juni 12-16",TRUE);
select HAUSNUMMER_DIN_5008("L11 2",TRUE); -- z.B in Mannheim
select HAUSNUMMER_DIN_5008("111. 2",TRUE);
select HAUSNUMMER_DIN_5008("Züricher Straße 17// 28",,TRUE);
-- Some special formating tests
SELECT HAUSNUMMER_DIN_5008("Mörikestr. 28 / 3",TRUE);
SELECT HAUSNUMMER_DIN_5008("8 - 6",TRUE);
SELECT HAUSNUMMER_DIN_5008("Straße des 17. Juni 12 - 16",TRUE);
SELECT HAUSNUMMER_DIN_5008("Straße des 17. Juni 12- 16",TRUE);
SELECT HAUSNUMMER_DIN_5008("Straße des 17. Juni 12 -16",FALSE);
-- Next one is not DIN 5008, but was a loop issue inside function
SELECT HAUSNUMMER_DIN_5008("8 /App.6",FALSE);
SELECT HAUSNUMMER_DIN_5008("8 /App.6",TRUE);
SELECT HAUSNUMMER_DIN_5008("8/App.6",TRUE);
如果您只需要街道名称,则必须使用HAUSNUMMER_DIN_5008()格式为FALSE,否则您无法在地址中找到numberpart。
SET @address := "Auf dem Brande 19a";
SELECT SUBSTRING(@address, 1, LOCATE(HAUSNUMMER_DIN_5008(@address, FALSE),@address)-1);
SET @address := "Straße des 17. Juni 12-16";
SELECT SUBSTRING(@address, 1, LOCATE(HAUSNUMMER_DIN_5008(@address, FALSE),@address)-1);
那是我的5美分 Christian Eickhoff
答案 4 :(得分:0)
第5行的错误1064(42000):您的SQL语法有错误;检查与您的MariaDB服务器版本相对应的手册,以便使用“END LOOP tokenLoop”附近的正确语法;
如果不是@oldString REGEXP' ^ [1-9]' THEN
SET @sp' at line 9
答案 5 :(得分:0)
对于来自Google的每个人:由于您不信任人类,因此我选择了这种方式:
SELECT
REGEXP_SUBSTR(address, '[a-z"äöüß"\-\. ]+') AS street ,
REGEXP_SUBSTR(address, '[0-9]+.*') AS number,
FROM
ADDRESSES
因为这也适用于:
Streetname 5
Streetname 5B
Streetname 5 B
Streetn.5B
Street-Name5
Streetname 5 (+trailing Space)
Street name5