2

为这个问题想出搜索参数时遇到了麻烦,所以我自己找不到答案。

      X 栏             |      
留言(信息1)|
消息(信息 2)(信息 1)|

以上是我需要处理的一栏的内容。查询的结果应该只是括号内的部分。问题是,有一个程序将两组信息保存在括号中,在这种情况下,LATTER ( info 1 ) 是我们想要的第一列,除此之外,我们必须为info 2添加第二列。

因此,我想象我需要将 if 子句与一个变量结合起来,例如,我可以依靠它来计算有多少左括号。如果 left_parentheses = 2,则 .... 否则,如果 left_parentheses = 1,则 ....

但我不知道如何在 SQL 中做到这一点,我也不知道如何在示例中的info 1 / 2之间进行分隔。

该示例的结果如下所示:

第 1 栏| 第 2 栏
 信息 1 |
 信息 1 | 信息 2

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

4

3 回答 3

4

查看内置函数charindexpatindexsubstring

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 添加到您的测试数据中,然后测试该视图是否在所有情况下都能满足您的需求。

于 2009-04-24T07:15:19.657 回答
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
于 2009-04-24T07:48:21.980 回答
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
  )
)

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

于 2009-04-24T07:41:58.313 回答