SQL连接多个表

时间:2012-01-26 14:02:10

标签: sql sql-server sql-server-2000

使用Microsoft SQL 2000,我想将多个表(A,B,C和D)连接在一起。我知道桌子A总是存在的。但是,我只知道至少有一种表格形式(B,C,D)存在。

我有什么方法可以做这样的事情来完成我想做的事情?

Select * form table a     
If table b exists left Join table b on a.id = b.id    
If table c exists left Join table c on a.id = c.id    
If table d exists left Join table d on a.id = d.id

4 个答案:

答案 0 :(得分:5)

您必须检查数据字典视图并使用动态SQL

declare @myquery varchar(1000)

set @myquery = 'Select * from a '
if exists (select * from sysobjects where xtype='U' and name = 'b')
begin
   set @myquery = @myquery + 'inner join b on b.id = a.id '
end
if exists (select * from sysobjects where xtype='U' and name = 'c')
begin
   set @myquery = @myquery + 'inner join c on c.id = a.id '
end
if exists (select * from sysobjects where xtype='U' and name = 'd')
begin
   set @myquery = @myquery + 'inner join d on d.id = a.id '
end

exec( @myquery)

我使用了sysobjects,但我们鼓励您使用Information Schema Views代替

并且,动态SQL上的大型DISCLAINER

<强>优点

  • 它提供了灵活性和可扩展性
  • 它可以减少编写的代码行数

<强>缺点

  • 它可能变得非常复杂和难以阅读。考虑嵌入引号中的引号以及其他类似的东西。
  • 它可能对代码稳定性产生不利影响。直到运行时才会知道某些动态SQL错误。 (例如,您引用不存在的表)
  • 动态SQL代码比等效的静态SQL更难测试。也可能无法测试动态SQL将遇到的每种可能情况,从而引入固有风险。
  • 在代码库中对动态SQL进行有效的影响分析会更加困难。
  • SQL注入和滥用 - 动态SQL更容易被滥用,并且总是比静态SQL更不安全
  • 动态SQL中的查询代码不受查询计划的约束,因此可能会错过此类优化。因此,它可能比等效的静态SQL
  • 由于SQL查询直到运行时才知道,因此可能难以对SQL动态代码进行性能调优(例如,确定表上可能需要的索引)

答案 1 :(得分:1)

以下是查询。 *永远不应该是查询的一部分,所以最好提一下列名。

declare @query varchar(1000)

set @query = 'Select ColumnName from a '
if exists (select Object_ID from sys.tables where name = 'b')
begin
   set @query = @query + 'inner join b on b.id = a.id'
end
if exists (select Object_ID from sys.tables where name = 'c')
begin
   set @query = @query + 'inner join c on b.id = c.id'
end
if exists (select Object_ID from sys.tables where name = 'd')
begin
   set @query = @query + 'inner join d on d.id = a.id'
end

exec( @query)

答案 2 :(得分:0)

你不能以这种方式进行条件连接。

你可以做一个普通的LEFT JOIN。如果没有行符合连接条件,那么这些列将为NULL:

Select *
from table a 
left Join table b on a.id = b.id
left Join table c on a.id = c.id
left Join table d on a.id = d.id

b。*列可能为NULL或c。*列可能为NULL或d。*列可能为NULL。

如果您需要选择第一个非NULL列,请使用COALESCE:

Select *, COALESCE(b.SOMECOLUMN, c.SOMECOLUMN, d.SOMECOLUMN) AS SOMECOLUMN
from table a 
left Join table b on a.id = b.id
left Join table c on a.id = c.id
left Join table d on a.id = d.id

正如评论者所说,如果表格不存在,这不起作用。我想我实际上会提倡继续创建表格,以便您的模式始终符合预期。动态SQL很难维护和调试,可以查询静态SQL和模式以确保它们满足使用元数据的期望(例如,如果缺少表,过程或视图将无效,并且可以显式查看依赖关系)

答案 3 :(得分:-1)

我猜你的意思是如果结果不是表本身。

SELECT * FROM TABLEA
OUTER JOIN TABLEB ON TABLEA.id = TABLEB.id
OUTER JOIN TABLEC ON TABLEA.id = TABLEC.id
OUTER JOIN TABLED ON TABLEA.id = TABLED.id

对于值不匹配的列,您将获得空值。

所以你可以用

过滤
WHERE TABLEB.id is not null