developer tip

같은 테이블에서 두 번 조인하는 가장 좋은 방법은 무엇입니까?

optionbox 2020. 8. 22. 08:41
반응형

같은 테이블에서 두 번 조인하는 가장 좋은 방법은 무엇입니까?


이것은 약간 복잡하지만 2 개의 테이블이 있습니다. 구조가 다음과 같다고 가정 해 봅시다.

*Table1*
ID
PhoneNumber1
PhoneNumber2

*Table2*
PhoneNumber
SomeOtherField

Table1.PhoneNumber1-> Table2.PhoneNumber 또는 Table1.PhoneNumber2-> Table2.PhoneNumber를 기준으로 테이블을 조인 할 수 있습니다.

이제 PhoneNumber1, PhoneNumber1에 해당하는 SomeOtherField, PhoneNumber2에 해당하는 SomeOtherField가 포함 된 결과 집합을 가져오고 싶습니다.

테이블을 두 번 조인하거나 ON 절에서 OR로 한 번 조인하는 두 가지 방법을 생각했습니다.

방법 1 :

SELECT t1.PhoneNumber1, t1.PhoneNumber2, 
   t2.SomeOtherFieldForPhone1, t3.someOtherFieldForPhone2
FROM Table1 t1
INNER JOIN Table2 t2
   ON t2.PhoneNumber = t1.PhoneNumber1
INNER JOIN Table2 t3
   ON t3.PhoneNumber = t1.PhoneNumber2

이것은 작동하는 것 같습니다.

방법 2 :

어떻게 든 다음과 같은 쿼리를 사용하려면-

SELECT ...
FROM Table1
INNER JOIN Table2 
   ON Table1.PhoneNumber1 = Table2.PhoneNumber OR
      Table1.PhoneNumber2 = Table2.PhoneNumber

나는 이것을 아직 작동시키지 않았고 그것을 할 방법이 있는지 확실하지 않습니다.

이를 수행하는 가장 좋은 방법은 무엇입니까? 어느 쪽도 간단하거나 직관적으로 보이지 않습니다 ...이 작업을 수행하는 더 간단한 방법이 있습니까? 이 요구 사항은 일반적으로 어떻게 구현됩니까?


먼저 전화 번호를 자연 키로 사용하지 않도록이 테이블을 리팩토링하려고합니다. 나는 자연 키의 팬이 아니며 이것이 좋은 예입니다. 자연 키, 특히 전화 번호와 같은 것은 자주 변경 될 수 있습니다. 변경 사항이 발생할 때 데이터베이스를 업데이트하는 것은 오류가 발생하기 쉬운 엄청난 골칫거리입니다. *

설명하는 방법 1 은 최선의 방법입니다. 명명 체계와 짧은 별칭으로 인해 약간 간결 해 보이지만 동일한 테이블을 여러 번 조인하거나 하위 쿼리 등을 사용하는 경우 별칭은 친구입니다.

나는 조금만 정리할 것입니다.

SELECT t.PhoneNumber1, t.PhoneNumber2, 
   t1.SomeOtherFieldForPhone1, t2.someOtherFieldForPhone2
FROM Table1 t
JOIN Table2 t1 ON t1.PhoneNumber = t.PhoneNumber1
JOIN Table2 t2 ON t2.PhoneNumber = t.PhoneNumber2

제가 한:

  • INNER를 지정할 필요가 없습니다. LEFT 또는 RIGHT를 지정하지 않는다는 사실을 암시합니다.
  • 기본 조회 테이블에 n- 접미사를 붙이지 마십시오.
  • 명확하게하기 위해 여러 번 사용할 테이블 별칭을 N 접미사로 지정합니다.

* DBA가 자연 키 업데이트의 골칫거리를 피하는 한 가지 방법은 기본 키와 외래 키 제약 조건을 지정하지 않는 것입니다. 나는 실제로 이것을 자주 본 적이 없다.


첫 번째는 Phone1 또는 (가능성이 더 높은) phone2가 null 일 수없는 경우에 좋습니다. 이 경우 내부 조인 대신 Left 조인을 사용하려고합니다.

두 개의 전화 번호 필드가있는 테이블이있는 경우 일반적으로 잘못된 신호입니다. 일반적으로 이것은 데이터베이스 디자인에 결함이 있음을 의미합니다.


UNION두 개의 조인을 결합 하는 사용할 수 있습니다 .

SELECT Table1.PhoneNumber1 as PhoneNumber, Table2.SomeOtherField as OtherField
  FROM Table1
  JOIN Table2
    ON Table1.PhoneNumber1 = Table2.PhoneNumber
 UNION
SELECT Table1.PhoneNumber2 as PhoneNumber, Table2.SomeOtherField as OtherField
  FROM Table1
  JOIN Table2
    ON Table1.PhoneNumber2 = Table2.PhoneNumber

The first method is the proper approach and will do what you need. However, with the inner joins, you will only select rows from Table1 if both phone numbers exist in Table2. You may want to do a LEFT JOIN so that all rows from Table1 are selected. If the phone numbers don't match, then the SomeOtherFields would be null. If you want to make sure you have at least one matching phone number you could then do WHERE t2.PhoneNumber IS NOT NULL OR t3.PhoneNumber IS NOT NULL

The second method could have a problem: what happens if Table2 has both PhoneNumber1 and PhoneNumber2? Which row will be selected? Depending on your data, foreign keys, etc. this may or may not be a problem.


My problem was to display the record even if no or only one phone number exists (full address book). Therefore I used a LEFT JOIN which takes all records from the left, even if no corresponding exists on the right. For me this works in Microsoft Access SQL (they require the parenthesis!)

SELECT t.PhoneNumber1, t.PhoneNumber2, t.PhoneNumber3
   t1.SomeOtherFieldForPhone1, t2.someOtherFieldForPhone2, t3.someOtherFieldForPhone3
FROM 
(
 (
  Table1 AS t LEFT JOIN Table2 AS t3 ON t.PhoneNumber3 = t3.PhoneNumber
 )
 LEFT JOIN Table2 AS t2 ON t.PhoneNumber2 = t2.PhoneNumber
)
LEFT JOIN Table2 AS t1 ON t.PhoneNumber1 = t1.PhoneNumber;

참고URL : https://stackoverflow.com/questions/4267929/whats-the-best-way-to-join-on-the-same-table-twice

반응형