【问题标题】:T-SQL How to convert comma separated string of numbers to integerT-SQL如何将逗号分隔的数字字符串转换为整数
【发布时间】:2013-09-15 16:00:02
【问题描述】:

我收到错误“将 nvarchar 值 '23,24,3,45,91' 转换为数据类型 int 时转换失败。”该错误似乎发生在 ON 子句上。 E.ID 是一个整数字段,而 F.LegalIssue 是一个由逗号分隔的整数的 varchar 字段。以下是出现该错误的代码。

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'

我已经为 on 子句尝试了下面的代码,但它只返回一个整数值,而不是整个整数字符串。

E.ID = cast(LEFT(F.LegalIssue,PATINDEX('%[^0-9]%',F.LegalIssue)-1) as int)

结果应包含五个用逗号分隔的整数。

【问题讨论】:

  • 请停止将逗号分隔的列表存储在单列中。你可能认为这是一个聪明而有用的设计,但它带来的问题多于解决的问题。数据库不是 JSON 容器!

标签: sql string comma delimited


【解决方案1】:

如果LegalIssue 包含一串以逗号分隔的数字,那么您确实需要一个关联表。缺少这一点,这里有一种方便(但不高效)的方式来进行连接:

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';

这会在列表前添加和后添加逗号以避免冲突,例如在“1,100,1000”中查找“10”。

【讨论】:

    【解决方案2】:

    使用 xml 数据类型,您可以像这样将字符串分解为整数。我想说的用户定义函数的好候选人:-)

    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) 
    

    【讨论】:

      【解决方案3】:

      您要么必须将 F.LegalIssue 标准化为多行,要么必须使用 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))
      

      如您所见,问题在于桌子的实际设计。您应该避免目前的设计,而选择1 to manymany to many 设计。

      这是一个如何使用递归 CTE 展平值的演示

      SQL Fiddle DEMO

      创建测试表和数据

      CREATE TABLE Tada(
        ID INT,
        SomeCommaString VARCHAR(50)
        )
      INSERT INTO Tada Values (1, '10'),(2,'5,6,12,16')
      

      扁平化表格

      ;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
      

      【讨论】:

        猜你喜欢
        • 2014-01-08
        • 1970-01-01
        • 2011-06-12
        • 1970-01-01
        • 2020-10-30
        • 1970-01-01
        • 2011-09-20
        相关资源
        最近更新 更多