首页 > 解决方案 > 如何在SQL中拆分顺序格式不一致的字符串

问题描述

我想拆分“记分员”列中的字符串,以便保留记分员姓名,但不保留分数类型(即删除括号和括号内的文本,以便将记分员姓名留在该字段中)。

Scorer
Ellis J.(Conversion Goal)
Ellis J.(Try)
Ellis J.(Conversion Goal)
Trueman J.(Try)
(Conversion Goal)Brough D.
(Try)McGillvary J.
(Try)McGillvary J.
(Penalty Goal)Brough D.
Ellis J.(Conversion Goal)

在此处输入图像描述

它应该如下所示。

Scorer
Ellis J.
Ellis J.
Ellis J.
Trueman J.
Brough D.
McGillvary J.
McGillvary J.
Brough D.
Ellis J.

标签: sqlsql-servertsql

解决方案


正确的解决方案是通过将另一列添加到表中的分数类型来修复数据库结构。事实上,您可能应该有一个分数类型表,并从该表中添加一个外键。

假设您无法更改数据库结构,最好在表示层完成。任何编程语言都应该能让你很容易地做到这一点。字符串操作不是 SQL 的强项。

话虽如此,它当然可以使用纯 T-SQL 来完成 - 使用简单的公共表表达式来获取括号索引 using charindex,并stuff在 select 语句中使用 case 表达式。

首先,创建并填充示例表(在以后的问题中保存我们这一步):

DECLARE @T AS TABLE
(
    Scorer nvarchar(100)
);

INSERT INTO @T (Scorer) VALUES
('Ellis J.(Conversion Goal)'),
('Ellis J.(Try)'),
('Ellis J.(Conversion Goal)'),
('Trueman J.(Try)'),
('(Conversion Goal)Brough D.'),
('(Try)McGillvary J.'),
('(Try)McGillvary J.'),
('(Penalty Goal)Brough D.'),
('Ellis J.(Conversion Goal)'),
-- Note: I've added some edge cases to the sample data:
('a row with (brackets) in the middle'),
('Just an open bracket (forgot to close '),
('Just a close bracket forgot to open)'),
('no brackets at all'),
('brackets ) in reversed order (');

然后,CTE:

WITH CTE AS
(
    SELECT  Scorer, 
            CHARINDEX('(', Scorer) As OpenBrackets,
            CHARINDEX(')', Scorer) As CloseBrackets
    FROM @T
)

选择语句:

SELECT  CASE WHEN OpenBrackets > 0 AND CloseBrackets > OpenBrackets
        THEN
           STUFF(Scorer, OpenBrackets, CloseBrackets - OpenBrackets + 1, '') 
        ELSE
            Scorer
        END As Scorer
FROM CTE

结果:

Scorer
Ellis J.
Ellis J.
Ellis J.
Trueman J.
Brough D.
McGillvary J.
McGillvary J.
Brough D.
Ellis J.
a row with  in the middle
Just an open bracket (forgot to close 
Just a close bracket forgot to open)
no brackets at all
brackets ) in reversed order (

推荐阅读