[英]T-SQL How to convert comma separated string of numbers to integer
I get the error "Conversion failed when converting the nvarchar value '23,24,3,45,91,' to data type int."我收到错误“将 nvarchar 值 '23,24,3,45,91' 转换为数据类型 int 时转换失败。” The error seems to be occuring on the ON clause.该错误似乎发生在 ON 子句上。 E.ID is an integer field while F.LegalIssue is a varchar field of integers separated by commas. E.ID 是一个整数字段,而 F.LegalIssue 是一个用逗号分隔的整数的 varchar 字段。 Below is the code with that error.下面是出现该错误的代码。
SELECT F.[FDTitle], E.PrimaryOpID as [FD Primary OP ID], F.County as [FD County], F.Status as [FD Status], F.IssueDate as [FD Date]
FROM [dbo].[tbl_FinalDetMain] F
LEFT OUTER JOIN [dbo].[tbl_lk_Exemptions_FD] E ON E.ID = F.LegalIssue
WHERE F.[FDNbr] = '2013-0041'
I have tried the code below for the on clause, but it only returns one integer value, instead of the entire string of integers.我已经为 on 子句尝试了下面的代码,但它只返回一个整数值,而不是整个整数字符串。
E.ID = cast(LEFT(F.LegalIssue,PATINDEX('%[^0-9]%',F.LegalIssue)-1) as int)
The result should include five integers delimited by commas.结果应包括五个用逗号分隔的整数。
If LegalIssue
contains a string of comma-delimited numbers, then you really want an association table.如果LegalIssue
包含一串以逗号分隔的数字,那么您确实需要一个关联表。 Lacking that, here is a convenient (but not efficient) way to do the join:缺少这一点,这是一种方便(但不是有效)的连接方式:
SELECT F.[FDTitle], E.PrimaryOpID as [FD Primary OP ID], F.County as [FD County],
F.Status as [FD Status], F.IssueDate as [FD Date]
FROM [dbo].[tbl_FinalDetMain] F LEFT OUTER JOIN
[dbo].[tbl_lk_Exemptions_FD] E
ON ','+F.LegalIssue+',' like '%,'cast(E.ID as varchar(255))+',%'
WHERE F.[FDNbr] = '2013-0041';
This prepends and postpends the list with commas to avoid conflicts, such as finding "10" in "1,100,1000".这会在列表前添加和后添加逗号以避免冲突,例如在“1,100,1000”中查找“10”。
Using xml datatype, you can explode your string to integers like this.使用 xml 数据类型,您可以像这样将字符串分解为整数。 Good candidate for a user defined function I would say :-)我会说用户定义函数的好人选:-)
declare @test varchar(max)
set @test = '1,2,3,4,5'
select
T2.item.value('(./text())[1]','int')
from
(select convert(xml,'<items><t>'+replace(@test,',','</t><t>')+'</t></items>') as xmldoc)
as xmltable
CROSS APPLY xmltable.xmldoc.nodes('/items/t') as T2(item)
You will either have to normalize the F.LegalIssue into many rows or you would have to use a LIKE您要么必须将 F.LegalIssue 标准化为多行,要么必须使用 LIKE
Something like就像是
CAST(E.ID A VARCHAR(50)) = F.LegalIssue
OR F.LegalIssue LIKE CAST(E.ID A VARCHAR(50)) + ',%'
OR '%,' + F.LegalIssue LIKE CAST(E.ID A VARCHAR(50)) + ',%'
OR '%,' + F.LegalIssue LIKE CAST(E.ID A VARCHAR(50))
As you can see, the actual design of the table is the issue.如您所见,表的实际设计是问题所在。 You should rather avoid the design you have currently, and opt for a 1 to many
or many to many
design.您应该避免当前的设计,并选择1 to many
或many to many
设计。
Here is a DEMO of how to flatten the values using a recursive CTE这是一个演示如何使用递归 CTE 展平值
Creating test table and data创建测试表和数据
CREATE TABLE Tada(
ID INT,
SomeCommaString VARCHAR(50)
)
INSERT INTO Tada Values (1, '10'),(2,'5,6,12,16')
Flattening the table把桌子弄平
;WITH Vals AS (
SELECT
ID,
CASE
WHEN CHARINDEX(',',SomeCommaString) = 0
THEN SomeCommaString
WHEN CHARINDEX(',',SomeCommaString) > 0
THEN LEFT(SomeCommaString,CHARINDEX(',',SomeCommaString) - 1)
END Val,
CASE
WHEN CHARINDEX(',',SomeCommaString) > 0
THEN RIGHT(SomeCommaString,LEN(SomeCommaString) - CHARINDEX(',',SomeCommaString))
ELSE NULL
END Remainder
FROM Tada
UNION ALL
SELECT
ID,
CASE
WHEN CHARINDEX(',',Remainder) = 0
THEN Remainder
WHEN CHARINDEX(',',Remainder) > 0
THEN LEFT(Remainder,CHARINDEX(',',Remainder) - 1)
END Val,
CASE
WHEN CHARINDEX(',',Remainder) > 0
THEN RIGHT(Remainder,LEN(Remainder) - CHARINDEX(',',Remainder))
ELSE NULL
END Remainder
FROM Vals
WHERE Remainder IS NOT NULL
)
SELECT ID, Val
FROM Vals
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.