2017-09-12 84 views
3

我試圖從位於英鎊(#)符號後面以及之後的任何空格之前的SQL Server 2012中的字符串獲取數字。例如,商店號碼。比方說,我們有以下幾點:SQL - 在英鎊(#)符號後從字符串獲取數字

Big Box Store #450 
Big Box Store #768 
Little Shop #2 
Widgets Warehouse #678 
Little Shop #5 
Widgets Warehouse #559 
Corner Boutiques #32 *CLOSED 
Corner Boutiques #67 *CLOSED 
Corner Boutiques #12 
Buy More #1047 SUPERSTORE 
1 Stop Shop #3 
1 Stop Shop #17 
You 2 Me #16 

我將返回以下:450,768,2,678,5,559,32,67,12,1047,3,17,16

正如你所看到的,並非所有的字符串在最後都有數字。他們中的一些甚至在商店的名字中有一個數字字符。我認爲解決這個問題的最好方法就是提取英鎊符號後面的數字。

有沒有辦法做到這一點?我已經看了下面的文章:

Query to get only numbers from a string

https://www.sqlservercentral.com/Forums/Topic456023-338-1.aspx

好像PATINDEX可能是很好用,但我不能確定我已經試過迄今沒有返回預期結果。

非常感謝!

回答

1

另一個類似的方法...使用來自Tyron的測試數據。即使數字之後沒有空格,這也是有效的。

DECLARE @t TABLE(
    MyString NVARCHAR(1000) 
); 

INSERT INTO @t VALUES 
('Big Box Store #450') 
,('Big Box Store #768') 
,('Little Shop #2') 
,('Widgets Warehouse #678') 
,('Little Shop #5') 
,('Widgets Warehouse #559') 
,('Corner Boutiques #32*CLOSED') --notice no space here 
,('Corner Boutiques #67 *CLOSED') 
,('Corner Boutiques #12') 
,('Buy More #1047 SUPERSTORE') 
,('1 Stop Shop #3') 
,('1 Stop Shop #17') 
,('You 2 Me #16'); 

select 
    SUBSTRING(MyString,CHARINDEX('#',MyString,0) + 1,case when PATINDEX('%[^0-9]%',RIGHT(MyString,LEN(MyString) - CHARINDEX('#',MyString,0))) = 0 then 99 else PATINDEX('%[^0-9]%',RIGHT(MyString,LEN(MyString) - CHARINDEX('#',MyString,0))) - 1 end) 
    --char version... 
    ,SUBSTRING(MyString,CHARINDEX('#',MyString,0) + 1,case when PATINDEX('%[^0-9]%',substring(MyString,CHARINDEX('#',MyString,0) + 1,LEN(MyString) - CHARINDEX('#',MyString,0) + 1)) = 0 then 99 else PATINDEX('%[^0-9]%',substring(MyString,CHARINDEX('#',MyString,0) + 1,LEN(MyString) - CHARINDEX('#',MyString,0) + 1)) - 1 end) 

from 
    @t 
+0

這看起來不錯,我測試過,它在數據集上工作,但我的數據類型是char(65)。您的解決方案似乎只適用於varchars和nvarchars。我做錯了什麼,或者有其他方法嗎?我甚至拋出了一些「CONVERT」函數來將它們轉換爲varchar(65),但那不起作用。謝謝! – jderekc

+0

@jderekc我添加了一個'CHAR'版本。 RIGHT()函數只接受'NVARCHAR'和'VARCHAR'。我用'SUBSTRING'取代了這個 – scsimon

+0

這很完美!每天學些新東西。非常感謝您的幫助,@ scsimon。 – jderekc

1

不是很漂亮,但似乎fullfill您的要求。 ;-)

DECLARE @t TABLE(
    MyString NVARCHAR(1000) 
); 

INSERT INTO @t VALUES 
('Big Box Store #450') 
,('Big Box Store #768') 
,('Little Shop #2') 
,('Widgets Warehouse #678') 
,('Little Shop #5') 
,('Widgets Warehouse #559') 
,('Corner Boutiques #32 *CLOSED') 
,('Corner Boutiques #67 *CLOSED') 
,('Corner Boutiques #12') 
,('Buy More #1047 SUPERSTORE') 
,('1 Stop Shop #3') 
,('1 Stop Shop #17') 
,('You 2 Me #16'); 

SELECT MyString 
     ,SUBSTRING(MyString 
       ,CHARINDEX('#', MyString) + 1 
       ,CASE(CHARINDEX(' ', SUBSTRING(MyString 
               ,CHARINDEX('#', MyString) + 1 
               ,LEN(MyString) - CHARINDEX('#', MyString) 
               ) 
           ) 
        ) 
        WHEN 0 THEN LEN(MyString) - CHARINDEX('#', MyString) 
        ELSE CHARINDEX(' ', SUBSTRING(MyString 
               ,CHARINDEX('#', MyString) + 1 
               ,LEN(MyString) - CHARINDEX('#', MyString) 
               ) 
           ) - 1 
        END 
       ) AS MyNumber 
    FROM @t 
+0

這工作雖然我發現有時商店將不包含數字的上市交易或者不會有間門店數量以及由scsimon預言「* CLOSED」標籤的空間。但是我的數據類型是一個char(65),它適用於你的解決方案,但由於某種原因,不適用於scsimon。 謝謝! – jderekc

1

請試試這個,使用pathindex

DECLARE @TABLE AS TABLE(
name_col varchar(250) 
) 

INSERT INTO @TABLE 
SELECT 
'Big Box Store #450' UNION ALL 
SELECT'Big Box Store #768'UNION ALL 
SELECT'Little Shop #2'UNION ALL 
SELECT'Widgets Warehouse #678'UNION ALL 
SELECT'Little Shop #5'UNION ALL 
SELECT'Widgets Warehouse #559'UNION ALL 
SELECT'Corner Boutiques #32 *CLOSED'UNION ALL 
SELECT'Corner Boutiques #67 *CLOSED'UNION ALL 
SELECT'Corner Boutiques #12'UNION ALL 
SELECT'Buy More #1047 SUPERSTORE'UNION ALL 
SELECT'1 Stop Shop #3 132132'UNION ALL 
SELECT'1 Stop Shop #17'UNION ALL 
SELECT'You 2 Me #16' 

SELECT 
LEFT(SUBSTRING(
    SUBSTRING(name_col,CHARINDEX('#',name_col) + 1,LEN(name_col)), 
    PATINDEX('%[0-9.-]%',SUBSTRING(name_col,CHARINDEX('#',name_col) + 1,LEN(name_col))), 8000), 
    PATINDEX('%[^0-9.-]%', SUBSTRING(SUBSTRING(name_col,CHARINDEX('#',name_col) + 1,LEN(name_col)), 
    PATINDEX('%[0-9.-]%', SUBSTRING(name_col,CHARINDEX('#',name_col) + 1,LEN(name_col))), 8000) + 'X') -1) 

FROM @TABLE 

你的懷疑是正確的,使用PATINDEX是解決方案,請檢查該鏈接以獲得更多信息。