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
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)
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)
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)
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