SQL 连接多个表

发布于 2024-12-29 15:14:54 字数 336 浏览 0 评论 0原文

我想使用 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

Using Microsoft SQL 2000, I will like to join multiples tables (A, B, C, and D) together. I know table A always exists. However, I only know at least one of the table form (B, C, D) exists.

Is there any way I could do something like this to accomplish what I am trying to do?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

少女情怀诗 2025-01-05 15:14:54

您必须检查数据字典视图并使用动态 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,但是我们鼓励您使用 信息架构视图 而是

动态 SQL 的重要免责声明

优点

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

缺点

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

You'll have to check the data dictionary views for that and use dynamic 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)

I've used sysobjects, however you are encouraged to use Information Schema Views instead

And, a BIG DISCLAINER ON DYNAMIC SQL

Advantages

  • It gives flexibility and scalability
  • It can reduce the number of lines of code written

Disadvantages

  • It can become very complex and difficult to read. Think about quotes embedded in quotes, and other such things.
  • It can have a detrimental effect on code stability. Some Dynamic SQL errors will not be known until run time. (An example of this is where you reference a non-existent table)
  • Dynamic SQL code is harder to test than the equivalent static SQL. It may also be impossible to test for every possible circumstance that your Dynamic SQL will encounter, thus introducing inherent risk.
  • It will be more difficult to conduct an effective impact analysis on Dynamic SQL in your code-base.
  • SQL injection and misuse – Dynamic SQL is more prone to misuse, and is invariably less safe than static SQL
  • The queries code within Dynamic SQL is not subject to a query plan, and as such optimisations may be missed. As such, it can be slower than the equivalent static SQL
  • As the SQL query is not known until runtime, it can be harder to performance-tune SQL Dynamic code (for example, determining the indexes that might be required on a table)
冰雪之触 2025-01-05 15:14:54

下面是查询。 * 永远不应该成为查询的一部分,因此最好提及列名称。

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)

Below is the query. The * should never be the part of the query so better to mention the column names.

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)
So要识趣 2025-01-05 15:14:54

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

你可以做一个普通的 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 和模式以确保它们满足预期(即,如果表丢失,则过程或视图将无效,并且可以显式查看依赖项)

You cannot do a conditional join in that way.

You can just do an ordinary LEFT JOIN. If no row matches the join criteria, those columns will be 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

The b.* columns may be NULL or the c.* columns may be NULL or the d.* columns may be NULL.

If you need to pick the first non-NULL column, use 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

As commenters have said, if the tables don't exist, this doesn't work. I think I would actually advocate going ahead and creating the tables so your schemas always match expectations. Dynamic SQL is a pain to maintain and debug and static SQL and schemas can be interrogated to ensure they meet expectations using metadata (i.e. a procedure or view will not be valid if a table is missing, and dependencies can be viewed explicitly)

思念满溢 2025-01-05 15:14:54

我猜你的意思是如果结果存在而不是表格本身。

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

etc来过滤

I guess you mean if the results exist not the tables themselves.

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

you will just get nulls for the columns where the value did not match.

so you can filter with

WHERE TABLEB.id is not null

etc

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文