-1

I have a one to many relationship between Course and Facilitator. The foreign key is in the Course table. How do I select a facilitator as distinct and have its multiple course IDs as columns next to the facilitator.

SELECT dbo.Facilitator.Fac_ID, dbo.Facilitator.Fac_Name, dbo.Course.Course_ID
FROM dbo.Course 
RIGHT JOIN dbo.Facilitator ON dbo.Course.FK_Facilitator = dbo.Facilitator.Fac_ID 
order by dbo.Facilitator.Fac_Name asc

returns:

enter image description here

instead, I want:

enter image description here

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Jnr
  • 1,504
  • 2
  • 21
  • 36
  • 2
    But if there are suddenly 3 (or 4) John items? – jarlh Mar 05 '15 at 13:11
  • 2
    Take a close look at that question and the accepted answer (_looks like some kind of duplicate to me_): http://stackoverflow.com/a/28696994/4584335 with only a little SQL skills you should be able to get your answer. – Rubik Mar 05 '15 at 13:30
  • 1
    Agreeing with @Rubik on this one. If this is SQL server, then use PIVOT. If this is damned near any other RDBMS, then you've got some work to do, especially if there can be a large variable number for each name. – JNevill Mar 05 '15 at 13:39
  • Forgot to mention, one facilitator can only belong to 1 or 2 courses, never more. – Jnr Mar 05 '15 at 13:42
  • Will take a look at that link – Jnr Mar 05 '15 at 13:42
  • possible duplicate of [Transposing rows into columns based on a condition sql](http://stackoverflow.com/questions/28696315/transposing-rows-into-columns-based-on-a-condition-sql) – Tab Alleman Mar 05 '15 at 14:19

1 Answers1

0

For pivoting, the column names should be defined. In your case you you do not have such a column name, as per your question. So we create sample column names like 1,2 etc.

First of all, get the column names for pivot

DECLARE @cols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + COLUMNNAME + ']', '[' + COLUMNNAME + ']')
               FROM    
               (
                   -- Generates random column names numerically from 1,2 etc
                   SELECT DISTINCT CAST(ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT 0))AS VARCHAR(4))COLUMNNAME 
                   FROM #TEMP
               ) PV 
               ORDER BY CAST(COLUMNNAME AS INT)

Now pivot the result. I have written the logic inside.

DECLARE @query NVARCHAR(MAX)
SET @query = '-- This outer query forms your pivoted result
             SELECT * FROM 
             (
                -- Source data for pivoting                
                SELECT ID,NAME,VALUE,
                CAST(ROW_NUMBER() OVER(PARTITION BY ID ORDER BY (SELECT 0))AS VARCHAR(4)) COLUMNNAME  
                FROM #TEMP 
             ) x
             PIVOT 
             (
                 --Defines the values in each dynamic columns
                 MIN(VALUE)
                 -- Get the names from the @cols variable to show as column
                 FOR COLUMNNAME IN (' + @cols + ')
            ) p            
            ORDER BY NAME;' 

EXEC SP_EXECUTESQL @query
Community
  • 1
  • 1
Sarath Subramanian
  • 20,027
  • 11
  • 82
  • 86