SQL joining multiple tables

我的梦境 提交于 2019-12-04 03:50:06

问题


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

回答1:


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)



回答2:


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)



回答3:


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)




回答4:


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



来源:https://stackoverflow.com/questions/9019224/sql-joining-multiple-tables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!