2014-07-10 6 views
0

다음은 두 가지 쿼리 (WHERE 쿼리 및 JOIN 쿼리)입니다. 두 쿼리는 서로 다른 결과 집합을 반환 할 가능성이 있습니다.이 두 쿼리의 차이점

더 많은 행을 반환 할 수있는 쿼리는 무엇입니까?
쿼리에서 다른 수의 행을 반환하기 위해 존재해야하는 데이터의 하위 집합은 무엇입니까?

WHERE 쿼리

SELECT COUNT(u.uid), r.name 
FROM role r 
LEFT JOIN users_roles ur ON r.rid = ur.rid 
LEFT JOIN users u ON ur.uid = u.uid AND u.status <> 0 
GROUP BY r.rid 

이 두 쿼리의 차이를 DIFF 결과를 반환하고 무슨 주된 이유는 무엇입니까 :

SELECT COUNT(u.uid), r.name 
FROM role r 
LEFT JOIN users_roles ur ON r.rid = ur.rid 
LEFT JOIN users u ON ur.uid = u.uid 
WHERE u.status <> 0 
GROUP BY r.rid 

쿼리를 가입?

답변

3

WHERE 쿼리는 조인 후 u.status <> 0을 확인합니다.
JOIN 쿼리는 조인의 일부로 u.status <> 0을 확인합니다.

따라서 WHERE 쿼리는 u.status = 0 인 경우 아무 것도 반환하지 않으며 JOIN 쿼리는 수행하지만 모든 필드는 users에서 NULL로 설정합니다.

덧붙여서, COUNT(u.uid)는 무수한 uid의 총 수를 세지려고하고 있습니다 만, 얼마나 많은 구별이 있습니까? uid가 있습니다.

+0

+1 즉, WHERE 절은 OUTER JOINS를 'INNER JOIN'으로 변경합니다. – VMai

+0

대단히 감사합니다. – user3826912

4

left outer join의 논리는 다음과 같습니다. 첫 번째 테이블의 모든 행을 두 번째 테이블의 모든 행과 비교합니다. 어떤 쌍이라도 on 조건과 일치하면 계속 유지하십시오. 첫 번째 테이블의 특정 행과 일치하는 행이 없으면 첫 행의 행을 유지하고 다른 모든 열을 NULL으로 만듭니다.

이 논리는 모든 경우에 적용됩니다. 그래서, 당신이 할 경우 :

select a.* 
from a left join 
    b 
    on 1 = 0; 

는 그런 다음 on 절은 항상 false로 평가에도 불구하고, a의 모든 행을 유지합니다. 필터는 어떤 의미로도 효과가 없습니다.

검색어에 동일한 문제가 발생했습니다. 가지고있을 때

ON ur.uid = u.uid AND u.status <> 0 

위의 표에 모든 행을 유지하는 것이 좋습니다. 0이 아닌 상태와 일치하는 것이 있으면 u.status에 해당 값을 사용하십시오. 그렇지 않은 경우 값은 NULL입니다.

대신이 : 왼쪽 성공하지 않습니다에 가입하고 상태 <> 0이 작성하는 "안전한"방법은 다음과 같습니다 :

WHERE u.status <> 0 

을 다음 당신은 정말이 말하는

WHERE u.status <> 0 or u.status IS NULL 

그러나 실제로는 left outer join의 일부이기 때문에 on 절에 조건을 넣는 것이 명확합니다.

+0

+1은 외부 조인의 논리를 설명합니다. – VMai

+0

그것이 작동하는 방법 지금 나에게 의미가 있습니다. 도움을 주셔서 감사합니다, 정말 감사드립니다. – user3826912

+0

@ user3826912 가장 도움이 된 답변을 수락하십시오. 답을 수락하면 답이없는 목록에서이 질문이 제거됩니다. – VMai