简体   繁体   中英

SQL Server select column names from multiple tables

I have three tables in SQL Server with following structure:

col1 col2 a1 a2 ... an, col1 col2 b1 b2 ... bn, col1 col2 c1 c2 ... cn

The two first records are the same, col1 and col2, however the tables have different lengths.

I need to select the column names of the tables and the result I'm trying to achieve is the followig:

col1, col2, a1, b1, c1, a2, b2, c2 ...

Is there a way to do it?

It's possible but result's is combined into single column of three table tables.

For example

SELECT A.col1 +'/' +B.col1 +'/' + C.col1  As Col1 ,
A.col2 +'/' +B.col2 +'/' + C.col2 As col2 ,a1, b1, c1, a2, b2, c2 ,
* FROM A
INNER JOIN B
ON A.ID =B.ID
INNER JOIN C 
ON C.ID = B.ID

SQL-Server is not the right tool to create a generic resultset . The engine needs to know what's coming out in advance . Well, you might try to find a solution with dynamic SQL ...

I want to suggest two different approaches.

Both would work with any number of tables, as long as all of them have the columns col1 and col2 with appropriate types.

Let's create a simple mokcup scenario before:

DECLARE @mockup1 TABLE(col1 INT,col2 INT,SomeMore1 VARCHAR(100),SomeMore2 VARCHAR(100));
INSERT INTO @mockup1 VALUES(1,1,'blah 1.1','blub 1.1')
                          ,(1,2,'blah 1.2','blub 1.2')
                          ,(1,100,'not in t2','not in t2');

DECLARE @mockup2 TABLE(col1 INT,col2 INT,OtherType1 INT,OtherType2 DATETIME);
INSERT INTO @mockup2 VALUES(1,1,101,GETDATE())
                          ,(1,2,102,GETDATE()+1)
                          ,(1,200,200,GETDATE()+200);
--You can add as many tables as you need

A very pragmatic approach:

Try this simple FULL OUTER JOIN :

SELECT * 
FROM @mockup1 m1
FULL OUTER JOIN @mockup2 m2 ON m1.col1=m2.col1 AND m1.col2=m2.col2
--add more tables here

The result

+------+------+-----------+-----------+------+------+------------+-------------------------+
| col1 | col2 | SomeMore1 | SomeMore2 | col1 | col2 | OtherType1 | OtherType2              |
+------+------+-----------+-----------+------+------+------------+-------------------------+
| 1    | 1    | blah 1.1  | blub 1.1  | 1    | 1    | 101        | 2019-03-08 10:53:20.257 |
+------+------+-----------+-----------+------+------+------------+-------------------------+
| 1    | 2    | blah 1.2  | blub 1.2  | 1    | 2    | 102        | 2019-03-09 10:53:20.257 |
+------+------+-----------+-----------+------+------+------------+-------------------------+
| 1    | 100  | not in t2 | not in t2 | NULL | NULL | NULL       | NULL                    |
+------+------+-----------+-----------+------+------+------------+-------------------------+
| NULL | NULL | NULL      | NULL      | 1    | 200  | 200        | 2019-09-24 10:53:20.257 |
+------+------+-----------+-----------+------+------+------------+-------------------------+

But you will have to deal with non-unique column names ... (This is the moment, where a dynamically created statement can help).

A generic approach using container type XML

Whenever you do not know the result in advance, you can pack the result in a container. This allows a clear structure on the side of your RDBMS and shifts the troubles how to deal with this set to the consumer.

  • The cte will read all existing pairs of col1 and col2
  • Each table's row(s) for the pair of values is inserted as XML
  • Pairs not existing in any of the tables show up as NULL

Try this out

WITH AllDistinctCol1Col2Values AS
(
    SELECT col1,col2 FROM @mockup1
    UNION ALL 
    SELECT col1,col2 FROM @mockup2
    --add all your tables here
)
SELECT col1,col2
     ,(SELECT * FROM @mockup1 x WHERE c1c2.col1=x.col1 AND c1c2.col2=x.col2 FOR XML PATH('row'),TYPE) AS Content1 
     ,(SELECT * FROM @mockup2 x WHERE c1c2.col1=x.col1 AND c1c2.col2=x.col2 FOR XML PATH('row'),TYPE) AS Content2
FROM AllDistinctCol1Col2Values c1c2
GROUP BY col1,col2;

The result

+------+------+-----------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+
| col1 | col2 | Content1                                                                                                  | Content2                                                                                                              |
+------+------+-----------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+
| 1    | 1    | <row><col1>1</col1><col2>1</col2><SomeMore1>blah 1.1</SomeMore1><SomeMore2>blub 1.1</SomeMore2></row>     | <row><col1>1</col1><col2>1</col2><OtherType1>101</OtherType1><OtherType2>2019-03-08T11:03:49.877</OtherType2></row>   |
+------+------+-----------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+
| 1    | 2    | <row><col1>1</col1><col2>2</col2><SomeMore1>blah 1.2</SomeMore1><SomeMore2>blub 1.2</SomeMore2></row>     | <row><col1>1</col1><col2>2</col2><OtherType1>102</OtherType1><OtherType2>2019-03-09T11:03:49.877</OtherType2></row>   |
+------+------+-----------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+
| 1    | 100  | <row><col1>1</col1><col2>100</col2><SomeMore1>not in t2</SomeMore1><SomeMore2>not in t2</SomeMore2></row> | NULL                                                                                                                  |
+------+------+-----------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+
| 1    | 200  | NULL                                                                                                      | <row><col1>1</col1><col2>200</col2><OtherType1>200</OtherType1><OtherType2>2019-09-24T11:03:49.877</OtherType2></row> |
+------+------+-----------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM