简体   繁体   English

SQL Server 从多个表中选择列名

[英]SQL Server select column names from multiple tables

I have three tables in SQL Server with following structure:我在 SQL Server 中有三个表,结构如下:

col1 col2 a1 a2 ... an, col1 col2 b1 b2 ... bn, col1 col2 c1 c2 ... cn 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.前两个记录是相同的,col1 和 col2,但是表的长度不同。

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 ... 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 . SQL-Server 不是创建通用结果集的正确工具。 The engine needs to know what's coming out in advance .发动机需要知道什么是未来提前出局。 Well, you might try to find a solution with dynamic SQL ...好吧,您可能会尝试使用动态 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.两者都可以处理任意数量的表,只要它们都具有适当类型的col1col2列。

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 :试试这个简单的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使用容器类型 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.这允许在您的 RDBMS 一侧有一个清晰的结构,并将如何处理这个集合的麻烦转移到消费者身上。

  • The cte will read all existing pairs of col1 and col2 cte 将读取所有现有的 col1 和 col2 对
  • Each table's row(s) for the pair of values is inserted as XML值对的每个表的行作为 XML 插入
  • Pairs not existing in any of the tables show up as NULL任何表中都不存在的对显示为 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> |
+------+------+-----------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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