SQL函数问题

发布于 2024-07-17 14:29:39 字数 611 浏览 2 评论 0原文

无法找到此问题的搜索参数,因此我无法自己找到答案。

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

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

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

但我不知道如何在 SQL 中做到这一点,而且我也不知道如何在示例中将 info 1 / 2 分开。

该示例的结果如下所示:

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

像往常一样,我将在此处等待提示时尝试寻找答案。 谢谢!

having trouble coming up with search parameters for this issue, so I can't find an answer on my own.

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

Above is the contents of one column I need to handle. The result of the query should be the part INSIDE the parentheses only. Problem is, there's one program that saves two sets of information in parentheses, in which case the LATTER (info 1) is the one we want in the first column, in addition to which we must add a second column for info 2.

So I'm imagining I need to combine an if clause with a variable I can depend on to count how many left parentheses there are, for example. If left_parentheses = 2, Then .... Else If left_parentheses = 1, Then ....

But I don't know how to do that in SQL, and I also don't know how to separate between info 1 / 2 in the example.

The result from the example would look like this:

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

As usual, I'll try to look for the answer while waiting for tips here. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

ゃ懵逼小萝莉 2024-07-24 14:29:39

查看内置函数 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('%(%)%(%)%', columnX)

将为您的第一个示例返回零,但不会为您的第二个示例返回零。

您还需要考虑如何处理错误数据,特别是 1) 没有括号的行,2) 左括号和右括号数量不等,3) 在两个带括号的“信息”之间有附加文本,4) 带有附加文本右括号后的文本。

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

Look at the builtin functions charindex, patindex, and substring.

charindex finds the positon of a specified character, patindex of a pattern, substring returns a portion of a string by position.

My advice would be to write a view over the table column X is in, that uses the above functions to provide two calculate columns. Then you could insert into result table select info1, info2 from columnX'stable;.

At least the calculated column info2 will involve a case statement to handle the case when there is only one parenthesized "info" in the source, something along these lines:

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;

In particular, patindex returns zero when a pattern is not found so:

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

would return zero for your first example but not your second example.

You'll also need to consider how you want to handle erroneous data, specifically 1) rows with no parentheses, 2) with unequal numbers of open and close parentheses, 3) with additional text between two parenthesized "infos", 4) with additional text after the closing parenthesis.

I'd encourage you to add examples of all these possibilities, as well as correctly formatted columnXes, to your test data, and then test that the view does what you want in all cases.

冰雪之触 2024-07-24 14:29:39

如果您有相当数量的数据,这将需要很长时间,但我怀疑是否有许多更好的使用 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

It will take ages if you have any decent amount of data but I doubt there are many better alternatives using 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
另类 2024-07-24 14:29:39

下面是我使用公共表表达式以 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。

Here's my go at it in SQL 2005 syntax using a Common Table Expression. I make no claims as to it's correctness or it's efficiency and I've made some assumptions about how you wanted it to work.

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

The where clause at the bottom is just to filter out any columns that either contain no brackets or contain brackets in a weird order and it uses NULL in Column2 when only one set of brackets are there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文