SQL函数问题

时间:2009-04-24 07:06:46

标签: sql tsql logic

无法为此问题提供搜索参数,因此我无法自行找到答案。

      Column X             |      
Message (info 1)           |
Message (info 2) (info 1)  |

以上是我需要处理的一列的内容。查询的结果应该只是括号内的部分。问题是,有一个程序在括号中保存两组信息,在这种情况下,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

像往常一样,我会在这里等待提示时尝试寻找答案。谢谢!

3 个答案:

答案 0 :(得分:4)

查看内置函数charindexpatindexsubstring

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

我的建议是在表格列X上写一个视图,它使用上面的函数来提供两个计算列。然后你可以insert into result table select info1, info2 from columnX'stable;

至少计算的列info2将涉及一个case语句来处理源中只有一个带括号的“info”的情况,这些内容如下:

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)在两个带括号的“infos”之间有附加文本,4 )在右括号后加上附加文字。

我建议您将所有这些可能性的示例以及格式正确的columnXes添加到测试数据中,然后在所有情况下测试视图是否符合您的要求。

答案 1 :(得分: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

答案 2 :(得分:1)

这是我在SQL 2005语法中使用Common Table Expression进行的。我没有声称它的正确性或效率,我已经对你希望它如何工作做出了一些假设。

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
  )
)

底部的where子句只是过滤掉任何不包含括号或以奇怪顺序包含括号的列,当只有一组括号时,它在Column2中使用NULL。