2012-06-11 5 views
4

이것은 아마도 SQL 데이터베이스 관리자 인 사람에게는 간단한 질문 일 뿐이지 만 필자는 필요할 때 데이터베이스를 충분히 오랫동안 사용할 수있게하는 C# 사람입니다.INNER와 왼쪽 조인에 대한 조언

데이터가 거의없는 새로운 데이터베이스가 있습니다.

내보기를 생성하는 데 사용할 쿼리가 필요하지만 LEFT 조인을 사용하는 방법/방법을 이해할 수없는 것 같습니다.

Packet

여러 Request 항목을 (한 사람이 5 개 가지 부품을 요구) 할 수 있으며 각 Request 항목 (보류, 취소, 특별 주문 완료 등의) 다른 Action 항목을 가질 수 있습니다.

ProductionDatabase

나는 다음과 같은 데이터 테이블 생성하는 쿼리를 만들 싶습니다

SELECT 
    P.EmpID AS Requestor, P.DateStamp AS Submitted, 
    T.Description AS RequestType, L.Description AS Line, R.PartNo, R.Workorder, R.Qty, 
    RT.Description AS ReasonType, S.Description AS Status, A.EmpID AS Stator, A.DateStamp AS Stated, R.MTF 
FROM Packet AS P 
    LEFT OUTER JOIN Request AS R ON (R.PacketID=P.ID) 
    LEFT OUTER JOIN Action AS A ON (A.RequestID=R.ID) 
    LEFT OUTER JOIN RequestType AS T ON (R.RequestTypeID=T.ID) 
    LEFT OUTER JOIN Line AS L ON (R.LineID=L.ID) 
    LEFT OUTER JOIN ReasonType AS RT ON (R.ReasonTypeID=RT.ID) 
    LEFT OUTER JOIN Status AS S ON (A.StatusID=S.ID) 

이 5 개 행을 반환합니다,하지만 몇 NULL 항목이 Status, StatorStated 거기에있다 .

그래서, 가입 내부로이 글을 쓰는 시도 :

SELECT 
    P.EmpID AS Requestor, P.DateStamp AS Submitted, 
    T.Description AS RequestType, L.Description AS Line, R.PartNo, R.Workorder, R.Qty, 
    RT.Description AS ReasonType, S.Description AS Status, A.EmpID AS Stator, A.DateStamp AS Stated, R.MTF 
FROM Packet AS P 
    INNER JOIN Request AS R ON (R.PacketID=P.ID) 
    INNER JOIN Action AS A ON (A.RequestID=R.ID) 
    INNER JOIN RequestType AS T ON (R.RequestTypeID=T.ID) 
    INNER JOIN Line AS L ON (R.LineID=L.ID) 
    INNER JOIN ReasonType AS RT ON (R.ReasonTypeID=RT.ID) 
    INNER JOIN Status AS S ON (A.StatusID=S.ID) 

널 (NULL) 항목이 이제 사라,하지만 지금은 단지 3 개 행이 돌아왔다.

어떤 버전을 사용해야하는지 어떻게 알 수 있습니까? ... 또는 LEFT와 INNER 조인을 함께 사용해야합니까?

+2

시작이 한 번 봐 : 결과는 당신이 원하는/무엇이 필요합니까. 어떤 조치가 취해 졌는지에 관계없이 모든 요청을 원한다면 요청 (또는 요청)에서 왼쪽 또는 오른쪽으로 참여하십시오. 당신이 속한 행동을 취한 요청 만 원하신다면 어쩌면 당신은 reasonType에서 Request.ReasonTypeID가 null 인 Request에 LEFT 조인을 원할 경우에는 절대 사용되지 않은 모든 Reason 유형을 원할 것입니다. – xQbert

+2

팁 : 일반적인 실수는 쿼리를 중단시키는 OUTER JOIN 뒤에 WHERE 절을 추가하는 것입니다. 예를 들어,'Packet'과'Request' 사이에'LEFT OUTER JOIN'이 있고'Request'에서'PartNo'를 참조하는'WHERE'를 추가하면'NULL' 값이나'JOIN'을 허용해야합니다 'OUTER'에서 'INNER'로 효과적으로 변경됩니다. 'ON' 절의'PartNo' 테스트는 "올바르게"작동합니다. – HABO

답변

4

어떤 버전을 사용해야하는지 어떻게 알 수 있습니까?

질문 만 대답 할 수 있습니다. null이있는 행 5 개 또는 null이없는 행 3 개를 원하셨습니까?

결과에서 알 수 있듯이 LEFT JOIN은 조인 할 테이블에 일치하는 레코드가 없기 때문에 (따라서 null 값) 레코드를 반환합니다.INNER JOIN은 합류하는 테이블에 일치하는 레코드가있는 경우에만 레코드를 반환합니다 (이는 5 대신 3 개의 결과가 나타나는 이유입니다).

염두에두고 엔드와 우수한 visual explanation of joins.

+0

답변으로 표시. 모든 것이 옳았습니다 (@xQbert의 저의 원래 게시물에있는 훌륭한 의견 포함). 그러나 [조인에 대한 시각적 설명]에 대한 귀하의 링크 (http://www.codinghorror.com/blog/2007/10/a-visual-explanation -of-sql-joins.html)은 무엇보다도 도움이되었습니다. – jp2code

6

어떤 버전을 사용해야하는지 어떻게 알 수 있습니까?

조인 조건이 일치하지 않는 경우 누락 된 열에 NULL 값을 사용 하시겠습니까? 아니면 결과 집합에 행이 없길 원하십니까?

  • 누락 된 열에 NULL을 원하면 외부 조인을 사용하십시오.
  • 전체 행을 없애려면 내부 조인을 사용하십시오.

LEFT 및 INNER 조인을 사용해야합니까?

각 결합에 대해 내부 결합인지 외부 결합인지를 고려해야합니다.

+0

이들 테이블 중 4 개는 열거 형 ('RequestType','Line','ReasonType' 및'Status')에 연결되므로 모두 1 대 1 유형의 매핑이어야합니다. 나머지 2 개 ('Packet'에서'Request'와'Request'''는'Action') 모두 1 대 다수입니다. 이론적으로는 NULL 값이 없어야합니다. 이로 인해 많은 데이터를 조사하는 데 많은 시간을 소비하게되었습니다. – jp2code