Search code examples
sqlsql-serversql-server-2008-r2sql-server-group-concat

sql server 2008 group_Concat() version BUT in different columns (NOT comma separated)


I am working on SQL Server 2008 R2. I have below 2 tables:

CREATE TABLE TRK_REQUEST(
REQUEST_ID int,
APPROVER_ID int CONSTRAINT app_ID_fk FOREIGN KEY REFERENCES TRK_APPROVER(APPROVER_ID),
APPROVER_LEVEL int)

CREATE TABLE TRK_APPROVER(APPROVER_ID int IDENTITY(1,1) PRIMARY KEY,
NAME Varchar(10))

INSERT INTO TRK_APPROVER VALUES('Approver_1'),('Approver_2'),('Approver_3')

INSERT INTO TRK_REQUEST VALUES(1, 1, 0),(1, 2, 1), (1, 3, 2)

What I want is a version of group_concat() BUT the values should be in separate columns (not comma separated)

I have tried joining the table,

SELECT REQ.REQUEST_ID, APP.NAME FROM TRK_REQUEST REQ
JOIN TRK_APPROVER APP
ON REQ.APPROVER_ID = APP.APPROVER_ID

But it gives me 3 different rows.

The desired output is like this,

| Request_ID  |    APPROVER_NAME1    |    APPROVER_NAME2    |    APPROVER_NAME3
+-------------+----------------------+----------------------+--------------------+
| 1           |    Approver_1        |    Approver_2        |    Approver_3

I found some matching examples here on SO, but not what i expected. Requesting your help.

SQL Fiddle


Solution

  • You could use dynamic crosstab:

    DECLARE @sql1   VARCHAR(4000) = ''
    DECLARE @sql2   VARCHAR(4000) = ''
    DECLARE @sql3   VARCHAR(4000) = ''
    
    SELECT @sql1 = 
    'SELECT
        r.REQUEST_ID' + CHAR(10)
    
    SELECT @sql2 = @sql2 +
    '   , [' + a.NAME + '] = MAX(CASE WHEN a.APPROVER_ID = ' + CONVERT(VARCHAR(10), a.APPROVER_ID) + ' THEN a.NAME END)' + CHAR(10)
    FROM (
        SELECT * FROM TRK_APPROVER
    )a
    ORDER BY a.APPROVER_ID
    
    SELECT @sql3 = 
    'FROM TRK_REQUEST r
    INNER JOIN TRK_APPROVER a
        ON a.APPROVER_ID = r.APPROVER_ID
    GROUP BY r.REQUEST_ID
    ORDER BY r.REQUEST_ID
    '
    
    PRINT (@sql1 + @sql2 + @sql3)
    EXEC (@sql1 + @sql2 + @sql3)
    

    SQL FIDDLE