Chr*_*son 2 sql-server t-sql string-splitting
SQL 服务器。兼容性级别 120。
我有一个表,其中一个 VARCHAR 列包含以分号分隔的整数值。我想对该列中的值进行 SELECT,就好像它们存在于某处的整数列中一样。
由于兼容级别,我不能使用 STRING_SPLIT。我也无法创建任何全局可用的函数。
但是,如果需要,我可以创建一个临时表。我的行动方针是什么?某种 WHILE 循环的嵌套(一个用于表的行,另一个用于字符串中的分号)?
更新:这可能是我想要实现的更好的解释:
假设我有以下表格。
CREATE TABLE Service
(
ServiceId int
, CustomerIds varchar(255)
);
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE Customer
(
CustomerId int
, CustomerName varchar(30)
);
Run Code Online (Sandbox Code Playgroud)
有一些数据
INSERT INTO Customer (CustomerId, CustomerName)
VALUES (1, 'John')
,(2, 'Niels')
,(3, 'Frank')
,(4, 'Barbie')
,(5, 'Holly')
,(6, 'Ebeneezer');
Run Code Online (Sandbox Code Playgroud)
INSERT INTO Service (ServiceId, CustomerIds)
VALUES (1, '4')
,(2, '2;3');
Run Code Online (Sandbox Code Playgroud)
假设我想为任何客户选择 Customer.CustomerName,该客户的 ID 显示在该表中任何行的 CustomerIds 中。
也就是说,我想检索Niels
,Frank
和Barbie
。
一个可能的解决方案可能是Splitting Delimited Strings Using XML in SQL Server。从那个帖子:
问题
本文将帮助开发人员寻找一种使用 XML 在单个查询中拆分分隔字符串的方法。我们通常使用用户定义的函数来执行此操作,您可能在很多地方都发现它根据传递的分隔符拆分字符串。但是,在没有用户定义函数的任何帮助的情况下在单个查询中分离字符串时,没有太多选择。我发现了一种更简单、更短的基于分隔符拆分任何字符串的方法。我将使用 XML 的力量来分割字符串,而不是使用用户定义的函数。
解决方案
例如,假设有一个字符串 'A,B,C,D,E',我想根据分隔符 ',' 拆分它。
第一步是将该字符串转换为 XML 并用一些开始和结束 XML 标记替换分隔符。
DECLARE @xml as xml,@str as varchar(100),@delimiter as varchar(10)
SET @str='A,B,C,D,E'
SET @delimiter =','
SET @xml = cast(('<X>'+replace(@str,@delimiter ,'</X><X>')+'</X>') as xml)
SELECT @xml
Run Code Online (Sandbox Code Playgroud)
字符串转换为 XML 后,您可以使用 XQuery 轻松查询
DECLARE @xml as xml,@str as varchar(100),@delimiter as varchar(10)
SET @str='A,B,C,D,E'
SET @delimiter =','
SET @xml = cast(('<X>'+replace(@str,@delimiter ,'</X><X>')+'</X>') as xml)
SELECT N.value('.', 'varchar(10)') as value FROM @xml.nodes('X') as T(N)
Run Code Online (Sandbox Code Playgroud)
| value |
|-------|
| A |
| B |
| C |
| D |
| E |
Run Code Online (Sandbox Code Playgroud)
更新 2019-12-09
根据您更新的问题,这是一个示例解决方案
set nocount on;
drop table if exists Service;
CREATE TABLE Service
(
ServiceId int
, CustomerIds varchar(255)
);
drop table if exists Customer;
CREATE TABLE Customer
(
CustomerId int
, CustomerName varchar(30)
);
INSERT INTO Customer (CustomerId, CustomerName)
VALUES (1, 'John')
,(2, 'Niels')
,(3, 'Frank')
,(4, 'Barbie')
,(5, 'Holly')
,(6, 'Ebeneezer');
INSERT INTO Service (ServiceId, CustomerIds)
VALUES (1, '4')
,(2, '2;3');
-----------------------
;WITH ServicesAsXml
AS (
SELECT ServiceId
,cast(('<X>' + replace(CustomerIds, ';', '</X><X>') + '</X>') AS XML) AS xmlcol
FROM Service
)
,ServicesSplit
AS (
SELECT ServiceId
,T.N.value('.', 'varchar(10)') AS CustomerId
FROM ServicesAsXml
CROSS APPLY xmlcol.nodes('X') T(N)
)
SELECT CustomerName
FROM Customer c
JOIN ServicesSplit ss ON ss.CustomerId = c.CustomerId
Run Code Online (Sandbox Code Playgroud)
| CustomerName |
|--------------|
| Barbie |
| Niels |
| Frank |
Run Code Online (Sandbox Code Playgroud)