使用SQL解析不一致的数据

时间:2016-04-27 17:50:19

标签: sql sql-server tsql text-parsing

我需要编写SQL来提取重复的位置代码并分离出子位置细节。但是,我使用的数据不遵循固定模式。

以下是位置代码的示例(真实表有超过5,000个位置):

JR-DY-TIN DY-RHOLD DY-PREQ-TIN GLVCSH GLFLR GLBOX1 GLBOX2 GLBOX3 GLBOXA GLBOXB GLBOXC GLBOXD GL GL0001 GL0002 GL0003 GL0014 …

当它是数字时,我能够为子位置细节创建一个新列,但这是我到目前为止的全部内容。

select 
  LocationCode,
  REVERSE(LEFT(REVERSE(LocationCode),PATINDEX('%[A-Za-z]%',  
  REVERSE(LocationCode))-1)) AS PaddedNumbers
from LocationTable 


Results...

LocationCode     PaddedNumbers     
------------     -------------     
JR-DY-TIN                          
DY-RHOLD                           
DY-PREQ-TIN                        
GLVCSH                             
GLFLR                              
GLBOX1           1                 
GLBOX2           2  
GLBOX3           3  
GLBOXA      
GLBOXB      
GLBOXC      
GLBOXD      
GL      
GL0001           0001   
GL0002           0002   
GL0003           0003   
GL0014           0014   

我仍然想知道如何在两个单独的列中显示以下内容:

  • 没有子位置详细信息的位置代码,例如GLBOX,或者只是 如果没有子位置,则为原始位置代码,例如, GLFLR。
  • 同时的数字和非数字子位置细节,例如对于 GLBOX有一列显示1,2,3,A,B,C,D,E,F。

编辑:如果我能够完成此任务,数据应如下所示:

LocationCode     MainLoc        SubLoc
------------     ---------      ------
JR-DY-TIN        JR-DY-TIN                         
DY-RHOLD         DY-RHOLD                  
DY-PREQ-TIN      DY-PREQ-TIN                  
GLVCSH           GLVCSH                  
GLFLR            GLFLR                 
GLBOX1           GLBOX          1               
GLBOX2           GLBOX          2
GLBOX3           GLBOX          3
GLBOXA           GLBOX          A
GLBOXB           GLBOX          B
GLBOXC           GLBOX          C
GLBOXD           GLBOX          D
GL               GL
GL0001           GL             0001    
GL0002           GL             0002    
GL0003           GL             0003    
GL0014           GL             0014    

感谢任何帮助。

环境:SQL Server 2008 R2。

3 个答案:

答案 0 :(得分:2)

您似乎想使用类似parseInt功能的内容,SQL Server 2008无效。您可以尝试使用cast,但这不适用于您的数据类型 - varchar

我建议使用case语句来解析你需要的复杂逻辑。即:

select 
  LocationCode,
  case when left(LocationCode,5) like 'GLBOX%' then substring(LocationCode,5,2) 
       when left(LocationCode,3) like 'GL0%' then substring(LocationCode,3,4)
       else 'null' end as ParsedLocationCode end
from LocationTable 

答案 1 :(得分:1)

约翰的回答似乎基本正确。我会把它写成:

select LocationCode,
       (case when LocationCode like 'GLBOX%' then right(LocationCode, 1) 
             when LocationCode like 'GL%' then right(LocationCode, 4)
        end) as ParsedLocationCode
from LocationTable 

这改变了:

  • substring()之前删除不必要的like
  • 修正了语法错误(可能是一个额外的end错字)。
  • 使用right(),只是因为它看起来更简单。

答案 2 :(得分:0)

DECLARE @LocationRef TABLE (Location NVARCHAR(20), Ref INT)

INSERT INTO @LocationRef VALUES
     ('JR-DY-TIN',0)
    ,('DY-RHOLD',0)
    ,('DY-PREQ-TIN',0)
    ,('GLVCSH',0)
    ,('GLFLR',0)
    ,('GLBOX1',6)
    ,('GLBOX2',6)
    ,('GLBOX3',6)
    ,('GLBOXA',6)
    ,('GLBOXB',6)
    ,('GLBOXC',6)
    ,('GLBOXD',6)
    ,('GL',0)
    ,('GL0001',3)
    ,('GL0002',3)
    ,('GL0003',3)
    ,('GL0014',3)

SELECT   Location AS LocationCode
    ,LEFT(Location,CASE Ref WHEN 0 THEN LEN(Location) ELSE Ref - 1  END)
    ,RIGHT(Location,CASE Ref WHEN 0 THEN 0 ELSE LEN(Location) - Ref + 1 END)
FROM @LocationRef

enter image description here