String.Join in SQL

2019-02-22 10:28发布

i want to select from a Table called RMA(simplified):

 idRMA| RMA_Number
 -----------------------
 1      RMA0006701
 2      RMA0006730
 3      RMA0006736
 4      RMA0006739
 5      RMA0006742

There is a junction table between RMA and tdefSymptomCode called trelRMA_SymptomCode:

 fiSymptomCode| fiRMA
 -----------------------
 1              1
 1              2
 2              2
 5              3
 7              3
 8              3
 2              5
 3              5
 4              5
 5              5

for the sake of completeness, this is tdefSymptomCode:

idSymptomCode    SymptomCodeNumber      SymptomCodeName
1                0000                   Audio problem
2                0100                   SIM problem
3                0200                   Appearance problem
4                0300                   Network problem
5                0500                   On/Off problem

Q:

every RMA can have 0-5 SymptomCodes. How can i join the SymptomCodeNumber with a delimiter like ':' together in a scalar-valued-function, so that i only get one varchar-value as result.

Something like this(where getRmaSymptomCodes is a SVF):

SELECT idRMA, RMA_Number, dbo.getRmaSymptomCodes(idRMA,':') AS Symptoms FROM RMA

This could be the symptoms of 3 different RMA's (all have exactly one symptom):

RMA_Number    SymptomCodeNumber
RMA0004823    0100
RMA0004823    0200
RMA0000083    0300
RMA0000084    0300
RMA0000084    0400

That should be concatenated as:

RMA0004823    0100:0200
RMA0000083    0300
RMA0000084    0300:0400

Thank you in advance

Update: Thanks to all i have created this working function

CREATE FUNCTION [dbo].[getRmaSymptomCodes]
(
    @idRMA int,
    @delimiter varchar(5)
)
RETURNS VARCHAR(8000)
AS
BEGIN
    DECLARE @Codes VARCHAR(8000) 
    SELECT @Codes = COALESCE(@Codes + @delimiter, '') +  tdefSymptomCode.SymptomCodeNumber
    FROM  RMA INNER JOIN
        trelRMA_SymptomCode ON RMA.IdRMA = trelRMA_SymptomCode.fiRMA INNER JOIN
        tdefSymptomCode ON trelRMA_SymptomCode.fiSymptomCode = tdefSymptomCode.idSymptomCode
    where idRMA=@idRMA
    order by SymptomCodeNumber
    return @Codes
END

4条回答
姐就是有狂的资本
2楼-- · 2019-02-22 11:01

Would this do?

DECLARE @Codes VARCHAR(8000) 
SELECT @Codes = COALESCE(@Codes + ', ': '') +  tdefSymptomCode.SymptomCodeNumber
    FROM  RMA INNER JOIN
        trelRMA_SymptomCode ON RMA.IdRMA = trelRMA_SymptomCode.fiRMA INNER JOIN
        tdefSymptomCode ON trelRMA_SymptomCode.fiSymptomCode = tdefSymptomCode.idSymptomCode
    where idRMA=2
    order by SymptomCodeNumber
return @Codes
查看更多
你好瞎i
3楼-- · 2019-02-22 11:05

Use the classic XML PATH-trick for this:

declare @RMA  as table(idRMA int, RMA_Number nvarchar(20))

declare @trelRMA_SymptomCode as table (fiSymptomCode int, fiRMA int)

declare @tdefSymptomCode as table (idSymptomCode int, SymptomCodeNumber nvarchar(4), SymptomCodeName nvarchar(20))

insert into @RMA values
(1,      'RMA0006701'),
(2,      'RMA0006730'),
(3,      'RMA0006736'),
(4,      'RMA0006739'),
(5,      'RMA0006742')

insert into @trelRMA_SymptomCode values
(1,              1),
(1,              2),
(2,              2),
(5,              3),
(7,              3),
(8,              3),
(2,              5),
(3,              5),
(4,              5),
(5,              5)

insert into @tdefSymptomCode values
(1,                '0000',                   'Audio problem'),
(2,                '0100',                   'SIM problem'),
(3,                '0200',                   'Appearance problem'),
(4,                '0300',                   'Network problem'),
(5,                '0500',                   'On/Off problem')

select RMA_Number,
 STUFF(
    (
    SELECT
      ':' + SymptomCodeNumber
    FROM @tdefSymptomCode def 
    join @trelRMA_SymptomCode rel on def.idSymptomCode = rel.fiSymptomCode
    where rel.fiRMA=rma.idRMA
    FOR XML PATH('')
    ), 1, 1, '')
from @rma rma

results in

RMA0006701  0000
RMA0006730  0000:0100
RMA0006736  0500
RMA0006739  NULL
RMA0006742  0100:0200:0300:0500
查看更多
Explosion°爆炸
4楼-- · 2019-02-22 11:07
select rma_number,
   stuff((select ':' + c.symptomcodenumber
    from trelRMA_SymptomCode r
    inner join tdefsymptomcode c on c.idsymptomcode = r.fisymptomcode
    where r.fiRMA = rma.idRMA
    order by c.symptomcodenumber
    for xml path('')), 1, 1, '') SymptomCodeName
from rma
查看更多
时光不老,我们不散
5楼-- · 2019-02-22 11:13

Here is something that should get you going:

ALTER FUNCTION [dbo].[GetUCColumns]
(@tableid INT, @index INT)
RETURNS VARCHAR (MAX)
AS
BEGIN

    DECLARE @cols varchar(max)

    SELECT @cols = COALESCE(@cols + ', ', '') + [name]
    FROM [sys].[columns]
    where object_id = @tableid AND column_id IN 
    (SELECT [column_id]
      FROM [sys].[index_columns]
      where object_id = @tableid AND @index = index_id)

    RETURN @cols
    END
查看更多
登录 后发表回答