SQL statement to combine main table and child table as columns?
There are two ways that I see you can do this - one would be with a static query the other with dynamic SQL.

Static query (even though you stated you have an unknown number of columns - this is how you would do this).:

select m.id,
  min(case when [key] = 'X' then value else null end) as 'x',
  min(case when [key] = 'y' then value else null end) as 'y',
  min(case when [key] = 'z' then value else null end) as 'z'
from main m
left join child c
  on m.id = c.mainid
group by m.id


see SQL Fiddle with Demo

Dynamic SQL version, this will create the query:

DECLARE @query  AS NVARCHAR(MAX) = ' '
DECLARE @rowcount int
DECLARE @rowNumber int = 0
DECLARE @case as nvarchar(max) = ' '
DECLARE @keyValue as varchar(1)

select distinct [key]
into #temp
from child

-- get the number of unique keys
set @rowcount = (select count(*) from #temp)

while @rowNumber &lt; @rowcount
  begin
    set @keyValue = (select top 1 [key] from #temp)

    set @case 
      = @case + 'min(case when [key] = ''' + @keyValue 
          + ''' then value else null end) as ''' + @keyValue + ''', '

    if @rowNumber &lt; @rowcount
      begin
        set @rowNumber = @rowNumber + 1

        delete from #temp where [key] = @keyValue
      end
  end

set @query 
  = 'select m.id, '+ substring(@case, 1, len(@case) -1) + '
     from main m
     left join child c
       on m.id = c.mainid
     group by m.id'

exec(@query)


see SQL Fiddle with Demo

The static version is portable but will not work with your dynamic requirement.