使用SELECT语句拆分streetname和number中的地址列

时间:2015-10-08 14:05:16

标签: mysql

我有一个带有地址列的mysql表。 现在我需要分别选择街道名称和号码。

Address

Wallstreet 20
New Yorkavenue 30
New London Street 40

需要:

Street:                Number:

Wallstreet             20
New Yorkavenue         30
New London Street      40

有什么想法吗? 提前谢谢!

6 个答案:

答案 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