String.Join in SQL - PullRequest
       34

String.Join in SQL

5 голосов
/ 27 января 2011

Я хочу выбрать из таблицы с именем RMA (упрощенно):

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

Существует таблица соединений между RMA и tdefSymptomCode, называемая trelRMA_SymptomCode:

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

для полноты, это 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

каждый RMA может иметь 0-5 Симптом-кодов. Как я могу объединить SymptomCodeNumber с разделителем, подобным ':', вместе в скалярной функции, чтобы в результате я получил только одно значение varchar. Примерно так (где getRmaSymptomCodes - SVF):

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

Это могут быть симптомы 3 разных RMA (все имеют ровно один симптом):

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

Это должно быть объединено как:

RMA0004823    0100:0200
RMA0000083    0300
RMA0000084    0300:0400

Заранее спасибо

Обновление : Спасибо всем, кто создал эту рабочую функцию

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 ]

4 голосов
/ 27 января 2011

Будет ли это делать?

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
3 голосов
/ 27 января 2011

Используйте для этого классический XML-трюк:

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

приводит к

RMA0006701  0000
RMA0006730  0000:0100
RMA0006736  0500
RMA0006739  NULL
RMA0006742  0100:0200:0300:0500
2 голосов
/ 27 января 2011
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
1 голос
/ 27 января 2011

Вот что вам нужно:

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
...