问题:
我正在尝试从多个表(表 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]
问题(限制):
该逻辑工作正常,但仅当存在 [ ] 时,这肯定是当前数据的情况,但是如果有新数据,则该逻辑将失败。
例如: 如果我们有以下字符串“需要一些时间,已收到的文档 - 未检查,杂项”,则由于字符串周围缺少 [ ],逻辑将失败。
我希望这是有道理的,并想知道是否有人可以帮助我克服这个限制。
请通过 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/证据 |
丢失文件 - 办公室 | 丢失文件 - 办公室 |
丢失文件 - 个人 | 丢失文件 - 个人 |
其他 | 其他 |
转介给决策者团队 | 转介给决策者团队 |
目标日期错误 | 目标日期错误 |