여러 조건을 추가하는 Mysql 조인과 위치의 차이점

최근 프로젝트에서 문제가 발생했는데 조금 흥미를 느꼈는데, 문제를 해결하고 관련 정보를 상담한 후 친구들과 공유할 기사를 작성할 계획입니다.

문제 현상:

문제는 매우 일반적인 널 포인터 문제로, 백엔드가 데이터베이스 데이터를 쿼리하고 관련 비즈니스 처리를 위해 순회할 때 널 포인터가 보고됩니다. 중단점 디버깅을 통해 쿼리에서 반환된 데이터에 문제가 있고 반환된 목록 컬렉션에 빈 데이터가 있음을 발견했습니다.
여기에 이미지 설명을 삽입하세요
어떻게 빈 데이터를 반환할 수 있는지 궁금합니다.

계속해서 문제 해결하기

실제로 SQL을 실행한 후 빈 데이터 행이 있는 것으로 나타났습니다. 먼저 형제들에게 SQL을 보여드리겠습니다(비즈니스 코드는 여기서 공개하기가 불편하고 주로 문제를 재현하기 위해 단순화되었습니다).

SELECT
	o.order_id,
	o.order_no,
	o.detail_id,
	o.product_id,
	o.batch,
	o.comp_brand_id,
	o.supplier_id,
	o.buyer
FROM
	tr_production_purchase_contract_and_order contractOrder
	LEFT JOIN t_daily_purchase_order o ON contractOrder.order_id = o.order_id 
	AND contractOrder.contract_id = '1585249657636917248' 
	AND contractOrder.del_flag = '0'

아마도 contract_id = '1585249657636917248'의 데이터를 검색하라는 의미일 것이며, 실행 결과 contractOrder.contract_id = '1585249657636917248' AND contractOrder.del_flag = '0' 조건이 적용되지 않는 것으로 나타납니다.
여기에 이미지 설명을 삽입하세요
왜 효과가 없나요? 처음 반응이 틀렸는데 꼼꼼히 살펴보니 문제가 없네요. 그래서 Left Join을 한 후 조건을 추가하는데 특별한 점이 있는지 궁금했는데, 정보를 확인해 보니 정말 특별하네요. 조인 후 조건을 추가하는 것은 where 조건과 다릅니다.

먼저 결론을 내리십시오.

  • Left Join
    on 뒤의 조건부 필터는 두 테이블이 생성한 전체 연결(Cartesian product) 임시 테이블을 필터링하는 것으로 on 이후의 조건 만족 여부에 관계없이 왼쪽 테이블의 모든 데이터가 반환되며, 그 값은 조건에 맞지 않는 오른쪽 테이블이 반환됩니다.

  • 오른쪽 조인은
    오른쪽 테이블의 모든 데이터가 최종적으로 반환되고, 자격이 없는 왼쪽 테이블의 값이 모두 null이라는 점만 제외하면 위와 동일하다.

  • Inner Join
    Inner Join은 조금 다르지만 두 테이블의 교차점이므로 최종 결과는 모든 조건을 만족하는 값이므로 이후의 조건이 적용될 수 있습니다.

  • where
    쿼리의 결과는 마지막에 where 조건에 따라 필터링되며 조건이 충족되는 경우에만 반환됩니다.

Left Join 시 On 이후 좌측 테이블의 데이터에 필터 조건을 추가하는 것은 소용이 없음을 알 수 있다. 위와 같은 문제가 발생한 이유도 오른쪽 테이블의 값만 쿼리를 하였기 때문에 조건이 만족되지 않아 쿼리로 반환된 데이터가 비어있는 것으로 확인되었습니다.

이러한 관점을 검증하기 위해 다음과 같은 테스트를 수행해 보겠습니다.
직원 테이블
여기에 이미지 설명을 삽입하세요
부서 테이블
여기에 이미지 설명을 삽입하세요
왼쪽 조인 단일 조건 쿼리

select 
t.emp_id,
t.name,
t.age,
d.dept_id,
d.dept_name
from t_emp t
left join t_dept d on t.dept_id = d.dept_id

여기에 이미지 설명을 삽입하세요
on 후 조건 추가

select 
t.emp_id,
t.name,
t.age,
d.dept_id,
d.dept_name
from t_emp t
left join t_dept d on t.dept_id = d.dept_id and t.emp_id = '4';

여기에 이미지 설명을 삽입하세요
on의 모든 조건을 일치 조건으로 사용하고 일치하지 않는 오른쪽 테이블은 null입니다.

where 뒤에 조건 추가

select 
t.emp_id,
t.name,
t.age,
d.dept_id,
d.dept_name
from t_emp t
left join t_dept d on t.dept_id = d.dept_id where t.emp_id = '4';

여기에 이미지 설명을 삽입하세요
일치시킨 후 필터링하면 결과는 단 하나의 레코드입니다.

내부 조인 다중 조건 쿼리

select 
t.emp_id,
t.name,
t.age,
d.dept_id,
d.dept_name
from t_emp t
inner join t_dept d on t.dept_id = d.dept_id where t.emp_id = '4';

여기에 이미지 설명을 삽입하세요
요약하다:

실제로 테이블을 연결할 때 2개의 테이블에 대한 전체 연결(Cartesian product, 즉 결합 가능한 모든 경우 a.rowCount*b.rowCount)을 먼저 수행한 후, 뒤에 있는 조건에 따라 필터링하고, 최종적으로 일치하는지 여부를 결정합니다. 왼쪽 조인이나 오른쪽 조인을 한 후 왼쪽 테이블이나 오른쪽 테이블의 데이터를 완성합니다.

개인적인 이해가 반드시 정확하지는 않습니다. 수정을 환영합니다.

참고글:
여러 조건의 조인 이해

Supongo que te gusta

Origin blog.csdn.net/weixin_44863237/article/details/132488280
Recomendado
Clasificación