2009-04-24 117 views
2

無法爲此問題提供搜索參數,所以我無法自己找到答案。SQL功能問題

​​

以上是我需要處理的一列的內容。查詢的結果應該是INSIDE括號中的部分。問題是,有一個程序在括號內保存了兩組信息,在這種情況下,LATTER(info 1)是我們想要的第一列中的信息,除此之外,我們還必須爲信息2添加第二列

所以我想象我需要結合一個if子句和一個變量,我可以依靠它來計算有多少個左括號。 如果left_parentheses = 2,那麼....否則如果left_parentheses = 1,那麼....

但我不知道如何在SQL中做到這一點,我也不知道如何分離在示例中的info 1/2之間。

該例的結果是這樣的:

 
Column 1 | Column 2 
Info 1 | 
Info 1 | Info 2 

像往常一樣,我會盡力去尋找答案,而等待的提示在這裏。謝謝!

回答

1

這裏是我使用公用表表達式在SQL 2005語法中的使用。我沒有聲稱它的正確性或效率,我對你希望如何工作做了一些假設。

WITH BracketIndeces AS 
(
    SELECT 
    ColumnX AS ColVal, 
    CHARINDEX('(', ColumnX) as first_open_bracket, 
    CHARINDEX('(', ColumnX, CHARINDEX('(', ColumnX)+1) as second_open_bracket, 
    CHARINDEX(')', ColumnX) as first_close_bracket, 
    CHARINDEX(')', ColumnX, CHARINDEX(')', ColumnX)+1) as second_close_bracket 
    FROM SomeTable 
) 
SELECT 
    CASE 
    WHEN second_close_bracket = 0 THEN 
     SUBSTRING(ColVal, first_open_bracket+1, first_close_bracket - first_open_bracket-1) 
    ELSE 
     SUBSTRING(ColVal, second_open_bracket+1, second_close_bracket - second_open_bracket-1)  
    END AS Column1, 
    CASE 
    WHEN second_close_bracket = 0 THEN 
     NULL 
    ELSE 
     SUBSTRING(ColVal, first_open_bracket+1, first_close_bracket - first_open_bracket-1) 
    END AS Column2 
FROM BracketIndeces 
WHERE first_open_bracket <> 0 
AND first_close_bracket <> 0 
AND first_open_bracket < first_close_bracket 
AND (
    (second_open_bracket = 0 AND second_close_bracket = 0) 
    OR 
    (second_open_bracket < second_close_bracket 
    AND second_open_bracket > first_close_bracket 
) 
) 

的地方在底部條款只是爲了過濾掉,要麼不含支架或包含在一個奇怪的順序括號的任何列,並在列2使用空當只有一組支架都在那裏。

+0

對此,我們不能表示感謝。我真的不得不把自己的頭撞到牆上,試圖自己做這件事,但那一天即將結束,我無法及時切斷它。你的解決方案就像一個魅力!再次感謝。 :) – Zan 2009-04-24 14:10:47

4

看看內置函數charindex,patindexsubstring

charindex找到指定字符patindex的位置,substring按位置返回一部分字符串。

我的建議是寫一個視圖在X列表中的表格列上,它使用上述函數提供兩個計算列。那麼你可以insert into result table select info1, info2 from columnX'stable;

至少計算列info2將涉及一個case語句來處理的情況下,只有一個括號源「信息」的東西沿着這些線路:

case when [some test using patindex too check for two parenthesized infos] 
then [some combination of patidex and substring to extract the second info] 
else null; 

特別是,PATINDEX返回零當一個模式沒有找到時如此:

patindex('%(%)%(%)%', columnX) 

將返回零爲您的第一個示例,但不是您的第二個示例。

您還需要考慮如何處理錯誤的數據,特別是1)沒有括號的行,2)不等數量的開括號和右括號,3)在兩個括號內的「信息」之間添加文本, 4)在右括號之後附加文本。

我鼓勵您將所有這些可能性的示例以及正確格式化的columnXes添加到您的測試數據中,然後測試視圖在所有情況下都能達到您的要求。

+0

謝謝你的提示,我打得四處一會兒PATINDEX函數,沒有得到它像預期的那樣,但它絕對的東西我會記住以供將來參考,我已經可以看到它的用途。 – Zan 2009-04-24 14:11:48

2

如果您有足夠數量的數據,這將需要很長時間,但我懷疑有很多更好的選擇使用SQL。

DECLARE @Table TABLE (TableID INT PRIMARY KEY, ColumnX VARCHAR(32)) 

INSERT INTO @Table VALUES (1, '(Info 1) (Info 2)'); 
INSERT INTO @Table VALUES (2, '(Info 1)'); 
INSERT INTO @Table VALUES (3, '(Info 10) (Info 20)'); 
INSERT INTO @Table VALUES (4, '(Info1') 
INSERT INTO @Table VALUES (5, '(Info1) (Info2') 
INSERT INTO @Table VALUES (6, '(Info1) Info2)') 
INSERT INTO @Table VALUES (7, 'Info1') 
INSERT INTO @Table VALUES (8, 'Info1)') 
INSERT INTO @Table VALUES (9, NULL); 

SELECT 
    TableID 
    , [Column1] = CASE WHEN PATINDEX('%(%)%', ColumnX) = 1 
       THEN SUBSTRING(ColumnX 
           , CHARINDEX('(', ColumnX) + 1 
           , CHARINDEX(')', ColumnX) 
           - CHARINDEX('(', ColumnX) - 1 
          ) 
       ELSE NULL END 
    , [Column2] = CASE WHEN PATINDEX('%(%)%(%)%', ColumnX) = 1 
       THEN SUBSTRING(ColumnX 
           , CHARINDEX('(', ColumnX, CHARINDEX('(', ColumnX) + 1) + 1 
           , CHARINDEX(')', ColumnX, CHARINDEX(')', ColumnX) + 1) 
           - CHARINDEX('(', ColumnX, CHARINDEX('(', ColumnX) + 1) - 1 
          ) 
       ELSE NULL END 
FROM @Table