使用视图和联合以及内部联接视图合并数据库表

时间:2014-06-26 21:52:06

标签: sql sql-server tsql

我有一种情况,我希望拥有多个数据库中所有数据的全局视图。每个数据库包含相同的表。

Database: DB1
Table: Companies
CompanyID      CompanyName
---------------------------------
1              Disney
2              Marvel
3              DC

Table: Employees
Employee ID    CompanyID      CompanyName      EmployeeName
------------------------------------------------------------
1              1              Disney           Donald Duck
2              1              Disney           Mickey Mouse
3              2              Marvel           Spiderman
4              2              Marvel           Captain America
5              3              DC               Superman
6              3              DC               Batman

Database: DB2
Table: Companies
CompanyID      CompanyName
---------------------------------
1              Warner Brothers
2              Hanna Barbera

Table: Employees
Employee ID    CompanyID      CompanyName      EmployeeName
------------------------------------------------------------
1              1              Warner Brothers  Wolverine
2              1              Warner Brothers  Cyclops
3              2              Hanna Barbera    Fred Flinstone
4              2              Hanna Barbera    Barney Rubble

我在数据库中创建了以下视图:DB1:

CREATE VIEW [CompaniesView]
as
select *
from [Companies] A
union all
select *
from DB2.dbo.[Companies] B

CREATE VIEW [EmployeesView]
as
select *
from [Employees] A
union all
select *
from DB2.dbo.[Employees] B

执行视图按预期工作。我的问题是当我加入2个观点时。

select C.CompanyName, E.CompanyName, E.EmployeeName 
  from CompaniesView as C
  join EmployeesView as E 
    on C.CompanyID = E.CompanyID

结果如下:

CompanyName       CompanyName      EmployeeName
------------------------------------------------------------
Disney            Disney           Donald Duck
Disney            Disney           Mickey Mouse
Warner Brothers   Warner Brothers  Wolverine
Warner Brothers   Warner Brothers  Cyclops
Marvel            Marvel           Spiderman
Marvel            Marvel           Captain America
Hanna Barbera     Hanna Barbera    Fred Flinstone
Hanna Barbera     Hanna Barbera    Barney Rubble
DC                DC               Superman
DC                DC               Batman
Warner Brothers   Disney           Donald Duck
Warner Brothers   Disney           Mickey Mouse
Warner Brothers   Warner Brothers  Wolverine
Warner Brothers   Warner Brothers  Cyclops
Hanna Barbera     Marvel           Spiderman
Hanna Barbera     Marvel           Captain America
Hanna Barbera     Hanna Barbera    Fred Flinstone
Hanna Barbera     Hanna Barbera    Barney Rubble

这些是我想要的结果:

CompanyName       CompanyName      EmployeeName
------------------------------------------------------------
Disney            Disney           Donald Duck
Disney            Disney           Mickey Mouse
Warner Brothers   Warner Brothers  Wolverine
Warner Brothers   Warner Brothers  Cyclops
Marvel            Marvel           Spiderman
Marvel            Marvel           Captain America
Hanna Barbera     Hanna Barbera    Fred Flinstone
Hanna Barbera     Hanna Barbera    Barney Rubble
DC                DC               Superman
DC                DC               Batman

如何使用仅使用视图来实现此功能?

3 个答案:

答案 0 :(得分:4)

您可以在视图和查询联接中包含数据库标识符。

create view dbo.CompaniesView
as
select 1 as DatabaseID, CompanyID, CompanyName
from DB1.dbo.Companies
union all
select 2 as DatabaseID, CompanyID, CompanyName
from DB2.dbo.Companies
GO

create view dbo.EmployeesView
as
select 1 as DatabaseID, Employee ID, CompanyID, CompanyName, EmployeeName
from DB1.dbo.Employees
union all
select 2 as DatabaseID, Employee ID, CompanyID, CompanyName, EmployeeName
from DB2.dbo.Employees
GO

select E.DatabaseID, C.CompanyName, E.CompanyName, E.EmployeeName 
from CompaniesView as C
join EmployeesView as E 
    on C.DatabaseID = E.DatabaseID
    and C.CompanyID = E.CompanyID

答案 1 :(得分:1)

看起来DB对于不同公司名称的重复CompanyID值感到困惑。

此查询可以为您提供所需的结果:

select C.CompanyName, E.CompanyName, E.EmployeeName from CompaniesView as C
inner join EmployeesView as E on C.CompanyID = E.CompanyID and C.CompanyName = E.CompanyName

注意最后添加的“和C.CompanyName = E.CompanyName”。

我还想注意,您可能需要考虑删除employees表中的公司名称列,并将外键放在引用公司表的employees表中的公司ID列上。除非您已经拥有密钥或其他工具,否则您可能会失去数据完整性,因为您已将其放在此处。

答案 2 :(得分:0)

根据建议,您可以通过在混合中添加公司名称来获得您正在寻找的结果。但是,考虑将您认为是主要参考ID(CompanyId,EmployeeId)的ID重复并指向不同公司/员工的想法并不适合我。这可能会在将来引起很多混乱和错误的代码。如果是我,我会在视图中删除companyId和EmployeeId,并构建一个可能是制造密钥的CompanyReference和EmployeeReference,如:DBName + CAST(CompanyId as nVarchar)。这样就可以避免对部分主键/外键进行任何假设。

*免责声明 - 我知道这会影响性能,我的建议只是提出可能导致正确轨道的建议