首页 > 解决方案 > T-SQL:在分隔符的不一致实例之间拆分字符值

问题描述

有一个字符串伴随着我需要从列中提取的值。我可以从大多数行中提取值,但在少数情况下,值具有不同的属性。这是问题的简化示例;

IF OBJECT_ID('TEMPDB..#TABLE') IS NOT NULL
    DROP TABLE #TABLE

CREATE TABLE #TABLE(
colSTRING           NVARCHAR(MAX)       NULL
);
INSERT INTO #TABLE (colSTRING)
VALUES (',SHOULD NOT BE STORED THIS WAY:22.67')
    ,(',SHOULD NOT BE STORED THIS WAY:46.32')
    ,(',SHOULD NOT BE STORED THIS WAY:23.45')
    ,(',SHOULD NOT BE STORED THIS WAY:66.67')
    ,(',SHOULD NOT BE STORED THIS WAY:22.35,ANOTHER BAD THING:OK')
;
SELECT * FROM #TABLE

输出:输出1

请注意,字符串末尾的“:”右侧有一个数字。这是我需要提取的数字。

然而,底行显示在同一单元格中有第二个字符串条目。我需要从该单元格中提取 22.35,同时省略字符串的其余部分。

这就是我到目前为止所拥有的;

SELECT 
    (RIGHT(colSTRING,CHARINDEX(':',REVERSE(colSTRING))-1)) [STRING NUMBER]
FROM #TABLE

输出:输出2

这适用于表中的其他值,但底行没有提取正确的值。它将字符串放在第二个字符串条目的“:”右侧。

有没有办法只在第一次出现“:”时使用这个逻辑?

标签: sql-servertsqlssms

解决方案


这就是我解决问题的方法,感谢@MartinSmith 的想法。我稍微调整了示例以显示它如何与超过 2 位数 (>=100.00) 的数字交互。

IF OBJECT_ID('TEMPDB..#TABLE') IS NOT NULL
    DROP TABLE #TABLE

CREATE TABLE #TABLE(
colSTRING           NVARCHAR(MAX)       NULL
);
INSERT INTO #TABLE (colSTRING)
VALUES (',SHOULD NOT BE STORED THIS WAY:22.67')
    ,(',SHOULD NOT BE STORED THIS WAY:46.32')
    ,(',SHOULD NOT BE STORED THIS WAY:23.45')
    ,(',SHOULD NOT BE STORED THIS WAY:766.67')
    ,(',SHOULD NOT BE STORED THIS WAY:22.35,ANOTHER BAD THING:OK')
;
SELECT * FROM #TABLE

解决方案:在这种情况下,每个字符串条目总是以逗号开头。我可以在 CASE 语句中使用该信息。当数字 <100.00 或 >=100.00 时,我为每种情况创建一个填充条目的列

SELECT ISNULL(CASE WHEN [2DIGITS] LIKE ',%' THEN NULL ELSE [2DIGITS] END,[3DIGITS]) [FIXED]
FROM(
SELECT 
    (RIGHT(colSTRING,CHARINDEX(':',REVERSE(colSTRING))-1)) [STRING NUMBER]
    ,SUBSTRING(colSTRING,1 + PATINDEX('%:[0-9][0-9].[0-9][0-9]%', colSTRING),5) [2DIGITS]
    ,SUBSTRING(colSTRING,1 + PATINDEX('%:[0-9][0-9][0-9].[0-9][0-9]%', colSTRING),6) [3DIGITS]
FROM #TABLE
)A

推荐阅读