【问题标题】:SQL - Extracting a substring between two charactersSQL - 提取两个字符之间的子字符串
【发布时间】:2018-08-20 18:12:23
【问题描述】:

我正在尝试从数据库中的长字符串中提取城市名称。以下是几个不同位置的数据示例。

"701 MONROE STREET NW RUSSELLVILLE, AL 35653 (34.514971, -87.736372)"
"1825 HOLTVILLE ROAD WETUMPKA, AL 36092 (32.558544, -86.221265)"

我想为城市名称创建一个列。我的想法是把所有的东西都放在逗号的左边和后面的空格的右边。我已经尝试了几种不同的方法来解决这个问题,但我可能会遗漏一些东西。

SELECT  left(Location, CHARINDEX(',', location)) as city FROM table

这将返回第一个逗号剩下的所有内容。

"701 MONROE STREET NW RUSSELLVILLE,
"1825 HOLTVILLE ROAD WETUMPKA,

但是现在我想返回逗号左边的所有内容和这个字符串中最后一个空格右边的所有内容,我不知道如何正确提取该信息。任何帮助,将不胜感激。

谢谢, 帕特

【问题讨论】:

  • "701 MONROE STREET NW RUSSELLVILLE, AL 35653 (34.514971, -87.736372)" "1825 HOLTVILLE ROAD WETUMPKA, AL 36092 (32.558544, -86.221265)" 是一个完整的地址
  • “...新泽西州大西洋城”怎么样?
  • 这就是规范化如此重要的原因......正如@NathanSkerl 所说明的那样,通常很难逆转。我可能会填写一张包含 ST、RD、ROAD、LN、LANE、NW、SW、NE 等所有可能性的表格......并找到最后一次出现的作为起点。假设它们是必需的,我想它会让你更接近。您可以检查它们是否存在,只需加倍下注。
  • 几个月前我遇到了同样的问题。我的解决方案是使用地址清理服务,例如Experian。有太多的变化需要考虑
  • 这是一个比看起来更难的问题。多词城市(“纽约市”)呢?还是带有定向第一个单词的城市名称(“北普拉特”)?还是含糊不清的城市名称(“Park City”、“Junction City”)?

标签: sql sql-server


【解决方案1】:

使用 REVERSE 可以处理以下问题:

SELECT reverse(
            left(
             reverse(
               left(
                 Location, 
                 CHARINDEX(',', location)-1
               )
              ),
              CHARINDEX(' ', reverse(
                 left(
                   Location, 
                   CHARINDEX(',', location)-1
                 )
               )
             )
           )
  )as city FROM table;

Fiddle

【讨论】:

  • 如果城市名称中有空格,这将不起作用。
  • @Sean Lange - 我同意,根本问题要解决起来要复杂得多。但是我在最初的问题中看到了两件事——一个功能需求(我不知道它是如何完成的——我很乐意学习解决方案)和一个关于如何定位最后一个空间的技术问题。这只是针对那部分(如果出现功能性解决方案,这个答案会很快消失)
  • 我不认为这是一个糟糕的答案。我只是想确保指出至少有那个洞。仅使用 t-sql 使这种事情成为 100% 是非常困难的(如果不是不可能的话)。问题不在于您的解决方案,而在于将 OP 置于这个可怕的地方的情况。 :)
【解决方案2】:

如果我在上面的评论中提到的 Google API 不是一个选项。您可以下载(甚至购买)邮政编码数据库。成本是名义上的。我建议每季度更新一次,因为邮政编码会随着时间而变化(添加/编辑/删除)

示例

Declare @YourTable table (id int,addr varchar(250))
Insert Into @YourTable values
(1,'701 MONROE STREET NW RUSSELLVILLE, AL 35653 (34.514971, -87.736372)'),
(2,'1825 HOLTVILLE ROAD WETUMPKA, AL 36092 (32.558544, -86.221265)')

Select A.ID
      ,StreetAddress =left(addr,nullif(charindex(Z.CityName,addr),0)-1)
      ,Z.CityName
      ,Z.StateCode
      ,Z.ZIPCode
 From @YourTable A
 Join [dbo].[OD-Zip] Z 
   on Z.ZipCode = substring(addr,nullif(patindex('%[0-9][0-9][0-9][0-9][0-9]%',addr),0),5)
      and charindex(Z.CityName,addr)>0
      and Z.ZipType='S'
      and Z.CityType='D'

退货

ID  StreetAddress           CityName        StateCode   ZIPCode
1   701 MONROE STREET NW    Russellville    AL          35653
2   1825 HOLTVILLE ROAD     Wetumpka        AL          36092

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 2013-12-11
    • 2021-01-17
    • 1970-01-01
    • 1970-01-01
    • 2020-11-13
    相关资源
    最近更新 更多