Sql 解析文本字段和联接表

Sql 解析文本字段和联接表,sql,sql-server,Sql,Sql Server,我有两张桌子 表1-2记录 Name NVARCHAR(50) PowerIds NVARCHAR(50) Name PowerIds 'Hulk' '1,3' 'Reed Richards' '2' 表2-3记录 PowerId INT PowerDescr NVARCHAR(50) PowerId PowerDescr 1 'Strength' 2 'Intelligence' 3

我有两张桌子

表1-2记录

Name NVARCHAR(50)
PowerIds NVARCHAR(50) 

Name               PowerIds
'Hulk'             '1,3'
'Reed Richards'    '2'
表2-3记录

PowerId INT
PowerDescr NVARCHAR(50)

PowerId   PowerDescr
1         'Strength'
2         'Intelligence'
3         'Durability'
通过以下方式实现这一目标最明智的方式是:

Name               Powers
'Hulk'             'Strength, Durability'
'Reed Richards'    'Intelligence'

我无法更改表结构,因为这是第三方产品。

最明智的方法是规范化您的表。将
英雄
表更改为

Name               PowerId
'Hulk'             1
'Hulk'             3
'Reed Richards'    2
或者从
英雄
表中移除异能,然后添加另一个表,该表仅包含对英雄和类似异能的引用

HeroID  PowerID
1       1
1       3
2       2

切勿在一列中存储多个数据 最聪明的方法是规范化您的表。将
英雄
表更改为

Name               PowerId
'Hulk'             1
'Hulk'             3
'Reed Richards'    2
或者从
英雄
表中移除异能,然后添加另一个表,该表仅包含对英雄和类似异能的引用

HeroID  PowerID
1       1
1       3
2       2
切勿在一列中存储多个数据 试试这个:

SELECT Name,
STUFF(
  (SELECT ',' + CAST(P.PowerDescr as VARCHAR(MAX))
  FROM fn_ParseCsvString(H1.PowerIds, ',') H2
  INNER JOIN Powers P ON P.PowerId = H2.ParsedString 
  FOR XML path('')),1,1,''
) AS Strength
FROM Heroes H1
功能:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION [dbo].[fn_ParseCsvString]
(   
    @csvString  VARCHAR(MAX),
    @delimiter  VARCHAR(MAX)
)
RETURNS @parsedStringTable TABLE (ParsedString VARCHAR(MAX))
AS
BEGIN
    DECLARE @startIndex INT, @targetedIndex INT
    SELECT
        @startIndex = 1
    WHILE @startIndex <= LEN(@CSVString)
    BEGIN
        SELECT  
            @targetedIndex = charindex(@Delimiter, @CSVString, @startIndex)
        IF @targetedIndex = 0
        BEGIN
            SELECT  
                @targetedIndex = len(@CSVString) + 1
        END
        INSERT  @parsedStringTable 
        SELECT 
            SUBSTRING(@CSVString, @startIndex, @targetedIndex - @startIndex)
        SELECT  @startIndex = @targetedIndex + LEN(@Delimiter)
    END
    RETURN
END


GO
将ANSI_空值设置为ON
去
在上设置带引号的\u标识符
去
创建函数[dbo]。[fn_ParseCsvString]
(   
@csvString VARCHAR(最大值),
@分隔符VARCHAR(最大值)
)
返回@parsedStringTable表(ParsedString VARCHAR(MAX))
作为
开始
声明@startIndex INT、@targetedIndex INT
挑选
@startIndex=1
当@startIndex时,尝试以下方法:

SELECT Name,
STUFF(
  (SELECT ',' + CAST(P.PowerDescr as VARCHAR(MAX))
  FROM fn_ParseCsvString(H1.PowerIds, ',') H2
  INNER JOIN Powers P ON P.PowerId = H2.ParsedString 
  FOR XML path('')),1,1,''
) AS Strength
FROM Heroes H1
功能:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION [dbo].[fn_ParseCsvString]
(   
    @csvString  VARCHAR(MAX),
    @delimiter  VARCHAR(MAX)
)
RETURNS @parsedStringTable TABLE (ParsedString VARCHAR(MAX))
AS
BEGIN
    DECLARE @startIndex INT, @targetedIndex INT
    SELECT
        @startIndex = 1
    WHILE @startIndex <= LEN(@CSVString)
    BEGIN
        SELECT  
            @targetedIndex = charindex(@Delimiter, @CSVString, @startIndex)
        IF @targetedIndex = 0
        BEGIN
            SELECT  
                @targetedIndex = len(@CSVString) + 1
        END
        INSERT  @parsedStringTable 
        SELECT 
            SUBSTRING(@CSVString, @startIndex, @targetedIndex - @startIndex)
        SELECT  @startIndex = @targetedIndex + LEN(@Delimiter)
    END
    RETURN
END


GO
将ANSI_空值设置为ON
去
在上设置带引号的\u标识符
去
创建函数[dbo]。[fn_ParseCsvString]
(   
@csvString VARCHAR(最大值),
@分隔符VARCHAR(最大值)
)
返回@parsedStringTable表(ParsedString VARCHAR(MAX))
作为
开始
声明@startIndex INT、@targetedIndex INT
挑选
@startIndex=1

而@startIndex谢谢。我在问题中添加了一条重要的免责声明。:)谢谢我在问题中添加了一条重要的免责声明。:)无效的对象名称“fn\u ParseCsvString”请再次检查。无效的对象名称“fn\u ParseCsvString”请再次检查。