如何查询具有不同结构的多个表?

时间:2018-06-14 07:56:13

标签: sql sql-server

我在C#应用程序中使用Sql-Server 2016。

我们说我有两张桌子:

CREATE TABLE Table_A
(
    UserID NVARCHAR2(15),
    FullName NVARCHAR2(25),
    Available NUMBER(1),
    MachineID NVARCHAR2(20),
    myDate date
);

CREATE TABLE Table_B
(
    UserID NVARCHAR2(15),
    FullName NVARCHAR2(25),
    Team NVARCHAR2(15),
    MachineID NVARCHAR2(20),
    Stuff NUMBER(2)
);

我想执行全局选择,以便从两个表中获取结果数据,以某种方式连接,当然,当其中一个表中不存在列时,该列将自动填充NULL,并且如果两个表上都存在列,则结果必须合并在一个列中。

弹出的第一个解决方案是UNION,缺少列的NULL别名,当然。问题是在运行时我不能事先知道询问哪些表,以便我可以预期列名。我需要一个更通用的解决方案。

两个表的预期结果必须如下所示:

user_Table_A; fullName_Table_A;  1;   machineID_Table_A; 12-JUN-18; NULL; 10;
user_Table_B; fullName_Table_B;      NULL; machineID_Table_B; NULL; team_Table_B; 20;

使用以下命令插入两个表的数据:

INSERT INTO Table_A VALUES ('user_Table_A', 'fullName_Table_A', 1, 'machineID_Table_A', TO_DATE('12-06-2018', 'DD-MM-YYYY'));

INSERT INTO Table_B VALUES ('user_Table_B', 'fullName_Table_B', 'team_Table_B', 'machineID_Table_B', 20);

1 个答案:

答案 0 :(得分:1)

你可以这样做。我没有时间完全调整它,所以可能有列的顺序。但也许它可以让你开始:

你还写道你使用的是Oracle - 我不确定你想要什么,但这是纯粹的sql-server版本。

<强> SQL:

IF OBJECT_ID('tempdb..#temp') IS NOT NULL
  /*Then it exists*/
  DROP TABLE #temp;
  GO
DECLARE @SQLList nvarchar(max)
DECLARE @SQLList2 nvarchar(max)

DECLARE @SQL nvarchar(max)

with table_a as (
select column_name  as Table_aColumnName,ORDINAL_POSITION from INFORMATION_SCHEMA.COLUMNS   
where TABLE_NAME  = 'table_a'
)

,
table_b as (
select column_name as Table_bColumnName,ORDINAL_POSITION from INFORMATION_SCHEMA.COLUMNS   
where TABLE_NAME  = 'table_b'

)
,preresult as (
select case when Table_aColumnName IS null then 'NULL as ' + Table_bColumnName else Table_aColumnName end as Table_a_ColumnName,case when Table_bColumnName IS null then 'NULL as ' +Table_aColumnName else Table_bColumnName end as Table_b_ColumnName
,a.ORDINAL_POSITION,b.ORDINAL_POSITION as Table_b_Ordinal from table_a a full join Table_B b  on a.Table_aColumnName = b.Table_bColumnName
)

select * into #temp from preresult

SET @SQLList = (
select distinct display = STUFF((select  ','+table_a_columnName from  #temp b  order by table_b_ordinal FOR XML PATH('')),1,1,'') from #temp a
)


SET @SQLList2 = (
select distinct display = STUFF((select  ','+table_b_columnName from  #temp b  order by Table_b_Ordinal FOR XML PATH('')),1,1,'') from #temp a
)

SET @SQL = 'select ' +@SQLList +' from dbo.Table_a union all select ' + @SQLList2 + ' from dbo.table_b'
exec(@SQL)

<强>结果:

enter image description here