2014-09-12 32 views
3

我试图提取###x###,###x##,有时候还有#x#。有时数字和x之间可能有空格。从本质上讲,我可能会碰到琴弦等使用SQL PATINDEX提取字符串,不同大小的子字符串

  • 720x60
  • 720x600
  • 720×60
  • 720_x_60
  • 的1x1

我使用PATINDEX()找到图案的第一次出现'%[0-9]%x%[0-9]%'。到现在为止还挺好。然后我使用PATINDEX()找到之后的第一个非数字字符串。这是我遇到麻烦的地方。我得到了截图中的结果。代码也在下面。

SELECT * 
    ,CASE WHEN StartInt > 0 
     THEN SUBSTRING(Placement, StartInt, SizeLength) ELSE NULL END AS PlacementSize 
FROM 
(SELECT Placement 
    --find the first occurrence of #*x*# 
    ,PATINDEX('%[0-9]%x%[0-9]%',Placement) AS StartInt 

    --find the first non-digit after that 
    ,PATINDEX(
     '%[^0-9]%' 
     ,RIGHT(
      Placement + '_' --this underscore adds at least one non-digit to find 
      ,LEN(Placement) 
       - 
      PATINDEX('%[0-9]%x%[0-9]%',Placement) - 5 
      ) 
     ) + 6 AS SizeLength 
FROM [Staging].[Client].[A01_FY14_Reporting_staging] 
WHERE [Date] > '2014-07-01') AS a 

结果:

enter image description here

+0

@Max当然。我需要在T-SQL中使用这个...使用正则表达式和其他语言超出了我的项目范围。 – Kyle 2014-09-12 15:53:42

回答

4

如果你正在处理一对数值,但还面临着脏数据,缺乏正则表达式的力量,这里就是你可以在TSQL中完成。

本质上讲,它看起来像你想打破一半的字符串为“X”,然后削减产出,直到你有数字只值。使用一组派生表,这变得相对容易(而不是难以阅读)

declare @placements table (Placement varchar(10)) 
insert into @placements values 
('720x60'), 
('720x600'), 
('720 x 60'), 
('720_x_60'), 
('1x1') 

SELECT LEFT(LeftOfX,PATINDEX('%[^0-9]%',LeftOfX) - 1) + 'x' + RIGHT(RightOfX, LEN(RightOfX) - PATINDEX('%[0-9]%', RightOfX) + 1) 
FROM (
    SELECT RIGHT(LeftOfX, LEN(LeftOfX) - PATINDEX('%[0-9]%', LeftOfX) + 1) AS LeftOfX, LEFT(RightOfX, LEN(RightOfX) - PATINDEX('%[0-9]%', REVERSE(RightOfX)) + 1) AS RightOfX 
    FROM (
     SELECT LEFT(p.Placement,x) AS LeftOfX, RIGHT(p.Placement,LEN(p.Placement) - x + 1) AS RightOfX 
     FROM (
      SELECT 
        p.Placement 
       , CHARINDEX('x',p.Placement) AS x 
      FROM @placements p 
      ) p 
     ) p 
    ) p 

这里的SQLFiddle example

首先,选择你的位置,你的“X”在放置的位置,等栏目,你从表中想要的。将其他列传递给派生表。

接下来,分割字符串成左右。

过程左,右两个查询,所述第一取结果的开始处的数字部分的权利,则在非数字部分结束的结果的左边。

编辑:固定的输出,现在选择的两个号码。

相关问题