【问题标题】:SQL Address ParsingSQL 地址解析
【发布时间】:2017-07-19 18:14:43
【问题描述】:

我有一个查询,我正在从一些地址解析单元#。

CASE WHEN Address1 LIKE '%apt %' THEN SUBSTRING(Address1, CHARINDEX('Apt', Address1), LEN(Address1))

当地址设置为:“123 Main St. Apt. 1A”时,这将正常工作。

我会得到“Apt. 1A”作为我的结果。

但是,在某些情况下,我的数据设置不同,例如“Apt. 2B 123 Fake Street”。当数据像这样设置时,我得到“Apt. 2B 123 Fake Street”

我正在寻找的结果是“Apt. 2B”

如何获取我的查询以获取“Ap​​t”。文本和以下所有文本直到下一个空格?

【问题讨论】:

  • 在 TSQL 中解析地址似乎不是一个好主意。

标签: sql sql-server ssms


【解决方案1】:

如果您对 UDF 持开放态度。

分层解析和提取字符串(charindex、left、right、...),我修改了一个 parse/split udf 以接受两个不相似的参数。

现在,解析地址可能是一个滑坡。在这里查看我的答案Address standardization within a database

示例

Declare @YourTable table (Address1 varchar(450))
Insert into @YourTable values 
 ('Apt. 2B 123 Fake Street')
,('123 Main St. Apt. 1A')
,('100 North Main St.')

Select A.Address1
      ,Apt = 'Apt. '+B.RetVal
 From @YourTable A
 Outer Apply [dbo].[udf-Str-Extract](' '+A.Address1+' ',' Apt. ',' ') B

退货

Address1                     Apt
Apt. 2B 123 Fake Street      Apt. 2B
123 Main St. Apt. 1A         Apt. 1A
100 North Main St.           NULL

有兴趣的 UDF

CREATE FUNCTION [dbo].[udf-Str-Extract] (@String varchar(max),@Delimiter1 varchar(100),@Delimiter2 varchar(100))
Returns Table 
As
Return (  

with   cte1(N)   As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)),
       cte2(N)   As (Select Top (IsNull(DataLength(@String),0)) Row_Number() over (Order By (Select NULL)) From (Select N=1 From cte1 N1,cte1 N2,cte1 N3,cte1 N4,cte1 N5,cte1 N6) A ),
       cte3(N)   As (Select 1 Union All Select t.N+DataLength(@Delimiter1) From cte2 t Where Substring(@String,t.N,DataLength(@Delimiter1)) = @Delimiter1),
       cte4(N,L) As (Select S.N,IsNull(NullIf(CharIndex(@Delimiter1,@String,s.N),0)-S.N,8000) From cte3 S)

Select RetSeq = Row_Number() over (Order By N)
      ,RetPos = N
      ,RetVal = left(RetVal,charindex(@Delimiter2,RetVal)-1) 
 From  (
        Select *,RetVal = Substring(@String, N, L) 
         From  cte4
       ) A
 Where charindex(@Delimiter2,RetVal)>1

)
/*
Max Length of String 1MM characters

Declare @String varchar(max) = 'Dear [[FirstName]] [[LastName]], ...'
Select * From [dbo].[udf-Str-Extract] (@String,'[[',']]')
*/

【讨论】:

  • 这个地方有没有代码高尔夫版本? (提醒我不要在 SQL 编码活动中与你作对)
  • @xQbert 我会随时与您合作。只是一个懒惰的编码员。我宁愿写一个函数,多次使用。
  • 我要保存这个以备后用
  • @scsimon 老实说,我喜欢这个。我用它来解析 JSON、XML、HTML 和许多其他的。
【解决方案2】:

有很多事情可能会导致此错误...并且此代码可能不适用于所有情况,具体取决于您的地址格式。假设格式是Apt,然后是空格AptNumberLetter,然后是空格......这可以工作。我把它拆开来展示它的作用。同样,正如 Martin 所说,规范化日期是您需要做的。

declare @table table (addy varchar(450))
insert into @table
values
('Apt. 2B 123 Fake Street'),
('123 Main St. Apt. 1A')

select
    addy
    ,CHARINDEX('Apt',addy)startLocation
    ,CHARINDEX(' ',addy,CHARINDEX('Apt',addy)) firstSpace
    ,CHARINDEX(' ',addy,CHARINDEX(' ',addy,CHARINDEX('Apt',addy)) + 1) endSpace
    ,substring(addy,CHARINDEX('Apt',addy),case when CHARINDEX(' ',addy,CHARINDEX(' ',addy,CHARINDEX('Apt',addy)) + 1) = 0 then 99 else CHARINDEX(' ',addy,CHARINDEX(' ',addy,CHARINDEX('Apt',addy)) + 1) end) FinalResult
from @table

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-23
    • 2015-09-14
    • 2013-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多