2

I want to concatenate column values with a separator and assign it to variable.

If column value is null, there's no need to add separator.

For example: A|B|C|D

If B is null A|C|D.

I tried with CONCAT function, but if B is null, it results in A||C|D

DECLARE @OldValue VARCHAR(8000); 

SELECT @OldValue =  CONCAT([FloorCode],'|',
                           [FloorName],'|',
                           [BuildingID],'|',
                           [HCMLocationCode],'|',
                           [IsActive]) 
FROM tblFloor_Master 
WHERE  FloorID = @FloorID; 

@FloorID is an input parameter of SP

RN92
  • 1,380
  • 1
  • 13
  • 32
  • What did you try, can you please add that code? – RN92 Jan 10 '19 at 04:59
  • Can you put your actual table with data and expected results? – Suraj Kumar Jan 10 '19 at 04:59
  • Possible duplicate of [How to concatenate text from multiple rows into a single text string in SQL server?](https://stackoverflow.com/questions/194852/how-to-concatenate-text-from-multiple-rows-into-a-single-text-string-in-sql-serv) – RN92 Jan 10 '19 at 05:03
  • @R.Nanayakkara - Added the code in the post –  Jan 10 '19 at 05:24
  • 1
    @SreelalT Check for NULL and do formatting. See answer below. Suraj Kumar's answers will also give you the desired output – RN92 Jan 10 '19 at 05:41

5 Answers5

4
SELECT @OldValue = CONCAT('',
    CASE WHEN [FloorCode] IS NULL THEN '' ELSE CONCAT([FloorCode],'|') END,
    CASE WHEN [FloorName] IS NULL THEN '' ELSE CONCAT([FloorName],'|') END,
    CASE WHEN [BuildingID] IS NULL THEN '' ELSE CONCAT([BuildingID],'|') END,
    CASE WHEN [HCMLocationCode] IS NULL THEN '' ELSE CONCAT([HCMLocationCode],'|') END,
    [IsActive])
FROM tblFloor_Master 
WHERE  FloorID = @FloorID; 
RN92
  • 1,380
  • 1
  • 13
  • 32
0

You can try the following query.

create table tempTable (id int identity(1, 1),col1 char(1), col2 char(1), col3 char(1), col4 char(1))
insert into tempTable values ('A', NULL, 'C', 'D')

select * into #NewTable from(
select id, col1 as Value from tempTable where col1 is not null
union
select id, col2 as Value from tempTable where col2 is not null
union
select id, col3 as Value from tempTable where col3 is not null
union
select id, col4 as Value from tempTable where col4 is not null
)a

SELECT  ID
       ,STUFF((SELECT '| ' + CAST(Value AS VARCHAR(10)) [text()]
         FROM #NewTable 
         WHERE ID = t.ID
         FOR XML PATH(''), TYPE)
        .value('.','NVARCHAR(MAX)'),1,1,' ') List_Output
FROM #NewTable t
GROUP BY ID

The output is as shown below

ID  List_Output
---------------
1     A| C| D

If you do not want to put space between values then you can try this

SELECT  ID
       ,STUFF((SELECT '|' + CAST(Value AS VARCHAR(10)) [text()]
         FROM #NewTable 
         WHERE ID = t.ID
         FOR XML PATH(''), TYPE)
        .value('.','NVARCHAR(MAX)'),1,1,'') List_Output
FROM #NewTable t
GROUP BY ID

In this case the output will be

ID  List_Output
---------------
1   A|C|D

You can also try the below actual query using stored procedure

create table tblFloor_Master (FloorID int identity(1, 1),
                              FloorCode char(1), 
                              FloorName char(1),
                              BuildingID char(1),
                              HCMLocationCode char(1))

insert into tblFloor_Master values ('A', NULL, 'C', 'D')

GO
--To create a procedure
create proc uspGetConcateValue
@FloorId int
as
BEGIN
    select * into #tblFloor_Master from(
    select FloorId, FloorCode as Value from tblFloor_Master where FloorCode is not null
    union
    select FloorId, FloorName as Value from tblFloor_Master where FloorName is not null
    union
    select FloorId, BuildingID as Value from tblFloor_Master where BuildingID is not null
    union
    select FloorId, HCMLocationCode as Value from tblFloor_Master where HCMLocationCode is not null
    )a

    SELECT  FloorId
           ,STUFF((SELECT '|' + CAST(Value AS VARCHAR(10)) [text()]
             FROM #tblFloor_Master 
             WHERE FloorId = t.FloorId
             FOR XML PATH(''), TYPE)
            .value('.','NVARCHAR(MAX)'),1,1,'') List_Output
    FROM #tblFloor_Master t
    where FloorID = @FloorId
    GROUP BY FloorId
END

Live demo here - Live Demo

Suraj Kumar
  • 5,547
  • 8
  • 20
  • 42
0

SELECT TRIM ('|' FROM regexp_replace( CONCAT('','|','COLB','|','','|','COLD','|','COLE') ,'[\|]+' ,'|' ,'g' ) )

0

Should be simple as doing replace, replace || to | then replace ||| to | since the maximum number of | is 3.

DECLARE @OldValue VARCHAR(8000); 

SELECT @OldValue =  replace(replace(CONCAT([FloorCode],'|',
                           [FloorName],'|',
                           [BuildingID],'|',
                           [HCMLocationCode],'|',
                           [IsActive]),'||','|'),'|||','|')
FROM tblFloor_Master 
WHERE  FloorID = @FloorID; 
RoMEoMusTDiE
  • 4,739
  • 1
  • 17
  • 26
  • Hi, given all of the items are empty you get ```||||``` before replacing, ```||``` after the inner replace and also ```||``` as final (wrong) result, since you watching for 3 times |. This solution is also wrong for ```|||```(2 adjacent fiels empty). The replace better could be ```||``` to ```|```, two times in a row: ```||||->||->|``` and ```|||->||->|``` for reducing up to 4 ```|``` to only 1. Switching inner and outer replace could solve the issue, too. – FrankM Jul 12 '21 at 08:04
0

I've only just discovered it too, but the CONCAT_WS (With Separator) function is designed for this problem. It has been available since SQL Server 2017.

DECLARE @OldValue VARCHAR(8000); 

SELECT @OldValue =  CONCAT_WS('|', 
                           [FloorCode],
                           [FloorName],
                           [BuildingID],
                           [HCMLocationCode],
                           [IsActive]) 
FROM tblFloor_Master 
WHERE  FloorID = @FloorID; 
J.Warren
  • 728
  • 1
  • 4
  • 14