有没有办法通过使用逗号作为分隔符来选择 SQL 查询中字符串的自定义部分?

问题描述 投票:0回答:1

问题:

我正在尝试从多个表(表 A 和 B)中进行选择,但这主要与我从表 B 中选择的唯一列有关。此列中的值包含一个字符串数组。

目标是去掉任何 [],然后查看字符串。有两种主要类型的字符串,一种仅包含文本,并且不以逗号分隔,另一种则包含文本和逗号的某些组合。

需要什么:

对于字符串不包含任何逗号的情况,则只需返回文本值。对于字符串确实包含单个或多个逗号的其他情况,返回第一个逗号之后的值。如果有超过 2 个或更多逗号,则需要在第一个逗号之后和第二个逗号之前返回字符串。

请查看代码以获取更多说明:

DROP TABLE IF EXISTS

\[dbo\].\[multi_string_db\]

GO

CREATE TABLE \[dbo\].\[multi_string_db\] (

multi_string nvarchar (256)  NULL

)

INSERT INTO \[dbo\].\[multi_string_db\] ( multi_string)

VALUES ('\[Additional time required, Time requested\]')

, ('\[Additional time required, Document requested\]')

, ('\[Additional time required, Missing documents - Personal, Other\]')

, ('\[Additional time required, Missing documents - Personal\]')

, ('Additional time required')

, ('Document Requested')

, ('Missing FPA/evidence')

, ('Missing documents - Office')

, ('Missing documents - Personal')

, ('Other')

, ('Referred to Decision Maker Team')

, ('Target date error')

期望的结果:

期望输出
要求时间
所需文件
丢失文件 - 个人
丢失文件 - 个人
需要额外时间
所需文件
缺少 FPA/证据
丢失文件 - 办公室
丢失文件 - 个人
其他
转介给决策者团队
目标日期错误

**到目前为止我尝试过的:**

SELECT 
    LTRIM(RTRIM(
        CASE 
            WHEN CHARINDEX('[', multi_string) > 0 AND CHARINDEX(']', multi_string) > 0
            THEN 
                CASE 
                    WHEN CHARINDEX(',', multi_string) > 0 AND CHARINDEX(',', multi_string, CHARINDEX(',', multi_string) + 1) > 0
                    THEN SUBSTRING(multi_string, CHARINDEX(',', multi_string) + 1, CHARINDEX(',', multi_string, CHARINDEX(',', multi_string) + 1) - CHARINDEX(',', multi_string) - 1)
                    WHEN CHARINDEX(',', multi_string) > 0
                    THEN SUBSTRING(multi_string, CHARINDEX(',', multi_string) + 1, CHARINDEX(']', multi_string) - CHARINDEX(',', multi_string) - 1)
                    ELSE SUBSTRING(multi_string, CHARINDEX('[', multi_string) + 1, CHARINDEX(']', multi_string) - CHARINDEX('[', multi_string) - 1)
                END
            ELSE
                LTRIM(RTRIM(multi_string)) -- If no brackets, return the original string
        END
    )) AS Result
            FROM dbo.[multi_string_db]

问题(限制):

该逻辑工作正常,但仅当存在 [ ] 时,这肯定是当前数据的情况,但是如果有新数据,则该逻辑将失败。

例如: 如果我们有以下字符串“需要一些时间,已收到的文档 - 未检查,杂项”,则由于字符串周围缺少 [ ],逻辑将失败。

我希望这是有道理的,并想知道是否有人可以帮助我克服这个限制。

sql-server azure substring charindex
1个回答
0
投票

请通过 XML 和 XQuery 尝试以下基于标记化的解决方案。

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE (ID INT IDENTITY PRIMARY KEY, multi_string NVARCHAR (256));
INSERT INTO @tbl( multi_string) VALUES 
('[Additional time required, Time requested]'), 
('[Additional time required, Document requested]'),
('[Additional time required, Missing documents - Personal, Other]'),
('[Additional time required, Missing documents - Personal]'),
('Additional time required'),
('Document Requested'),
('Missing FPA/evidence'),
('Missing documents - Office'),
('Missing documents - Personal'),
('Other'),
('Referred to Decision Maker Team'),
('Target date error');
-- DDL and sample data population, end

DECLARE @separator CHAR(1) = ',';

SELECT t.multi_string --, c, t2.token_count
    , result = CASE
        WHEN t2.token_count = 1 THEN TRIM(c.value('(/root/r/text())[1]', 'NVARCHAR(100)'))
        WHEN t2.token_count > 1 THEN TRIM(c.value('(/root/r[2]/text())[1]', 'NVARCHAR(100)'))
        ELSE 'Alarm! Some edge case.'
    END 
FROM @tbl AS t
CROSS APPLY (SELECT TRY_CAST('<root><r><![CDATA[' + 
    REPLACE(TRIM('[]' FROM multi_string), @separator, ']]></r><r><![CDATA[') + 
    ']]></r></root>' AS XML)) AS t1(c)
CROSS APPLY (SELECT c.value('count(/root/r)', 'INT')) AS t2(token_count);

输出

多字符串 结果
[需要额外时间,要求时间] 要求时间
[需要额外时间,要求提供文件] 所需文件
[需要额外时间,缺少文件 - 个人,其他] 丢失文件 - 个人
[需要额外时间,缺少文件 - 个人] 丢失文件 - 个人
需要额外时间 需要额外时间
所需文件 所需文件
缺少 FPA/证据 缺少 FPA/证据
丢失文件 - 办公室 丢失文件 - 办公室
丢失文件 - 个人 丢失文件 - 个人
其他 其他
转介给决策者团队 转介给决策者团队
目标日期错误 目标日期错误
© www.soinside.com 2019 - 2024. All rights reserved.