SQL Server从多个表中选择列名称

时间:2019-03-08 08:43:27

标签: sql sql-server

我在SQL Server中有三个具有以下结构的表:

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

前两个记录相同,col1和col2,但是表的长度不同。

我需要选择表的列名,而我想要实现的结果是followig:

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

有办法吗?

2 个答案:

答案 0 :(得分:0)

这是可能的,但结果被合并到三个表的单列中。

例如

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

答案 1 :(得分:0)

SQL Server不是创建通用结果集的正确工具。引擎需要提前知道的内容。好吧,您可能会尝试使用动态SQL ...

找到解决方案

我想提出两种不同的方法。

只要它们的列col1col2都具有适当的类型,两者都可以使用任何数量的表。

我们先创建一个简单的 mokcup场景

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

一种非常务实的方法:

尝试简单的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

结果

+------+------+-----------+-----------+------+------+------------+-------------------------+
| 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 |
+------+------+-----------+-----------+------+------+------------+-------------------------+

但是您将不得不处理非唯一列名 ...(此时,动态创建的语句可以提供帮助)。

使用容器类型XML的通用方法

每当您不事先知道结果时,都可以将结果包装在容器中。这样可以使RDBMS的结构清晰,并将麻烦的处理方式转移给使用者。

  • CTE将读取所有现有的col1和col2对
  • 该值对的每个表的行都作为XML插入
  • 任何表中都不存在的对显示为NULL

尝试一下

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;

结果

+------+------+-----------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+
| 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> |
+------+------+-----------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------+