2009-04-24 69 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