2012-01-26 5 views
4

Microsoft SQL 2000을 사용하여 여러 테이블 (A, B, C 및 D)을 함께 결합하고자합니다. 나는 테이블 A가 항상 존재한다는 것을 압니다. 그러나 나는 적어도 하나의 테이블 형식 (B, C, D)이 존재한다는 것을 알고 있습니다.여러 테이블에 가입하는 SQL

내가하려는 일을 수행하기 위해 이와 같은 작업을 수행 할 수있는 방법이 있습니까?

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 

답변

5

당신은 DYNAMIC의 ON BIG DISCLAINER을 내가 sysobjects을 사용했습니다

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) 

그러나 당신이 Information Schema Views 대신

를 사용하는 것이 좋습니다, 동적 SQL 그런에 대한 데이터 사전 뷰를 확인하고 사용하고 있습니다 SQL

장점

  • 그것은 그것은 작성된 코드의 줄 수를 줄일 수있는 유연성과 확장 성
  • 을 제공

단점

  • 그것은 매우 될 수 있습니다 복잡한 읽기 어려움. 따옴표에 포함 된 따옴표 및 다른 것들을 생각해보십시오.
  • 코드 안정성에 해로운 영향을 줄 수 있습니다. 일부 동적 SQL 오류는 런타임까지 알 수 없습니다. (예를 들어, 존재하지 않는 테이블을 참조하는 경우)
  • 동적 SQL 코드는 동등한 정적 SQL보다 테스트하기가 어렵습니다. 동적 SQL이 발생할 수있는 모든 상황을 테스트하는 것이 불가능할 수도 있으므로 고유 한 위험이 발생합니다.
  • 코드 기반에서 동적 SQL에 대한 효과적인 영향 분석을 수행하는 것이 더 어려울 것입니다.
  • 동적 SQL은 오용되기 쉽고 정적 SQL보다 항상 안전합니다.
  • 동적 SQL 내의 쿼리 코드는 쿼리 계획의 대상이 아니므로 이러한 최적화가 누락 될 수 있습니다. 따라서 동등한 정적 SQL보다 느릴 수 있습니다
  • 런타임까지 SQL 쿼리를 알 수 없으므로 SQL 동적 코드를 성능 조정하는 것이 더 어려울 수 있습니다 (예 : 테이블에 필요할 수있는 인덱스를 결정하는 것))
+2

+1 -이 링크 만 추가합니다 : www.sommarskog.se/dynamic_sql.html – Lamak

+0

여기 * 사용법을 피해야하며 대신 Object_ID가 선호됩니다. – Pankaj

+0

@StackOverflow 사용자 : 그렇지 않습니다. select *는 select fieldname보다 식별 할 수있는 차이가 없습니다. http://milambda.blogspot.com/2008/01/whats-wrong-with-count.html –

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 

ㄴ * 열 NULL 또는 C 일 수있다 * 열 NULL 또는 (D) 일 수있다 * 열 NULL 일 수있다... 댓글이 말했듯이 테이블이 존재하지 않는 경우

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 

,이 작동하지 않습니다 : 첫 번째 NULL이 아닌 열을 선택해야하는 경우

, 유착를 사용합니다. 나는 실제로 당신의 스키마가 항상 기대에 부합 할 수 있도록 테이블을 만드는 것을 실제로 옹호 할 것이라고 생각합니다. 동적 SQL은 유지 보수 및 디버그 및 정적 SQL에 대한 통증이며 스키마가 메타 데이터를 사용하여 기대에 부합하는지 조사 할 수 있습니다 (예 : 테이블이 누락되어 있고 종속성을 명시 적으로 볼 수있는 프로 시저 또는 뷰는 유효하지 않음).

+0

은 아마 *, COALESCE ... –

+1

@Cade 루를 원한다. 동적 SQL을 사용하면이 문제를 해결할 수있는 하나의 옵션이됩니다. –

+1

그게 효과가 있습니까? * table *이 존재하지 않더라도 (테이블의 행 *이 아닌)? – adelphus

-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 

값이 일치하지 않는 열에 대해서는 null이 생깁니다.

WHERE TABLEB.id is not null 

+1

아니요, 그는 테이블 자체에 대해 말하고 있습니다. –

1

아래는 쿼리입니다 함께

그래서 당신은 필터링 할 수 있습니다. *는 쿼리의 일부가 아니어야하므로 열 이름을 언급하는 것이 좋습니다. (가) * 테이블 * B, C 및 D가 존재하는 경우 영업 이익은 모르고, 난 당신이 오해 생각 -.

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

SQL 2000의 'sys.tables'는 SQL 2005에만 있습니다. –

+0

예 :) sysobjects는 매우 일반적인 용어입니다. 그래서 개발자의 관점에서 특정 상황에서 이해할 수있는 개발 중에 특정 단어를 사용하는 것이 더 낫다. 내가 맞기를 바란다. – Pankaj

+0

@JamesWiseman이 말하는 것은 당신이'sys.tables'를 사용하고 있다는 것이다. 존재하지 않는다. SQL 2000에서 쿼리가 작동하지 않습니다. – Lamak

관련 문제