Search code examples
sqlxmlsql-server-2008for-xml-path

Combine different table columns with UNION and use XML to differentiate the column names


Though this works to return the right results,

SELECT r.KeyColumn as '@Key', t1.Key1 as 'Key1', t1.Col1 as 'Col1' 
FROM @resultset r
INNER JOIN Table1 t1 ON t1.Col1 = 'SomeCondition'
--FOR XML PATH('Column1')  -- This errors out when used with union, works as a seperate query.

UNION
SELECT r.KeyColumn as '@Key', t2.Key1 as 'Key2', t2.Col2 as 'Col2' 
FROM @resultset r
INNER JOIN Table2 t2 ON t2.Col1 = 'SomeCondition2'
--FOR XML PATH('Column2')  -- This errors out when used with union, works as a seperate query.

Results:

@Key Key1  Col1
1   1  Table1Col1
1   1  Table2Col

The problem is that the results together doesn't differentiate between the different naming I'm trying to use, because of the UNION. How can I get both to display under one resultset but with different names? I'm thinking XML to do this, but am unable to figure out how?

What's an optimal way to combine different queries with different results/number of rows and put everything under one big XML?

Ok, the best I could come up with is:

SELECT r.KeyColumn as '@Key', t1.Key1 as 'Key1', t1.Col1 as 'Col1',  '' as 'Key2', '' as 'Col2'
          FROM @resultset r
    INNER JOIN Table1 t1 ON t1.Col1 = 'SomeCondition'
    --FOR XML PATH('Column1')  --Error

     UNION 

     SELECT r.KeyColumn as '@Key', '' AS 'Key1', '' as 'Col1', t2.Key1 as 'Key2', t2.Col2 as 'Col2' 
    FROM @resultset r
    INNER JOIN Table2 t2 ON t2.Col1 = 'SomeCondition2'
    --FOR XML PATH('Column2')  -- Error

Will give me results (again, as expected because of the Union)

    @Key    Key1        Col1        Key2    Col2
---------------------------------------------------------------------------
    1       1           Table1Col1
    1                               1       Table2Col

I still want to get my results as an XML thus:

<Root>
<Column1 Key="1">
  <Key1>1</Key1>
  <Col1>Table1Col1</Col1>
</Column1>

<Column2 Key="1">
  <Key2>1</Key2>
  <Col2>Tabl2Col</Col2>
</Column2>
</Root>

or something on these lines:

 <Root Key="1">
    <Column1>
      <Key1>1</Key1>
      <Col1>Table1Col1</Col1>
    </Column1>

    <Column2>
      <Key2>1</Key2>
      <Col2>Tabl2Col</Col2>
    </Column2>
    </Root>

Solution

  • Are you looking for something like this?

    declare @T table 
    (
      KeyColumn int,
      Col1 varchar(10),
      Col2 varchar(10)
    )
    
    insert into @T values(1, 'Col1', 'Col2')
    
    select (
             select KeyColumn,
                    Col1
             from @T
             for xml path('Query1'), type       
           ),
           (
             select KeyColumn,
                    Col2
             from @T
             for xml path('Query2'), type       
           )
    for xml path('root')
    

    Result:

    <root>
      <Query1>
        <KeyColumn>1</KeyColumn>
        <Col1>Col1</Col1>
      </Query1>
      <Query2>
        <KeyColumn>1</KeyColumn>
        <Col2>Col2</Col2>
      </Query2>
    </root>