2017-12-28 25 views
0

나는 네 개의 테이블이 무엇이든).선택 항목은

select c.id, c.name from company c 
left outer join order o on o.company_id = c.id 
left outer join quote q on q.company_id = c.id 
left outer join invoice i on i.company_id = c.id 
where o.number is not null or q.number is not null or i.number is not null 

그러나 order, quoteinvoice 테이블이 매우 큰 :

나는이 쿼리를 썼다. 따라서 join은 쿼리가 영원히 실행되도록합니다 (하나의 조인은 O (m * n)이고 세 조인은 O (m * n * p * q) 임).

이 쿼리는 기본적으로 각 쿼리 (O (m * n) + O (m * p) + O (m * q))에서 단 하나의 조인으로 3 회 실행될 수 있지만, 최적의 솔루션입니다.

오라클

에 대한
+0

접근 방법에있어서의 위험은 세 테이블이 각각 회사마다 여러 행을 포함 할 가능성이 높다는 것입니다. 따라서 회사 1에는 5 개의 견적서, 2 개의 주문서, 2 개의 청구서가있을 수 있습니다. 총 20 개의 행 (5 * 2 * 2)이 해당 회사에만 반환됩니다. 열악한 성능을 야기하는 테이블의 기본 크기가 아니지만 회사가 여러 번 나타날 수 있으며 이러한 중복은 이후의 조인으로 확대됩니다. – Steve

+0

@ 스티브 맞아. 이해해. 나는 심지어 쿼리를 작성하기도 전에 실제로 그것을 알았다. 나는 왜 내가 갇혀 있었는지 설명하기 위해 해결책에 대한 나의 접근법을 보여 주려했다. – ryvantage

답변

2

이 세 가지 주문 테이블의 조합 않는 하위 쿼리에 가입입니다 :

SELECT 
    c.id, c.name 
FROM company c 
INNER JOIN 
(
    SELECT company_id FROM order 
    UNION 
    SELECT company_id FROM quote 
    UNION 
    SELECT company_id FROM invoice 
) t 
    ON c1.id = t.company_id 

하는 것은 노동 조합 쿼리가 자동으로 중복 company_id을 제거해야합니다을 등이 존재하는 별개의 회사 세 테이블 중 하나에서 해당 하위 쿼리의 결과 집합에 있어야합니다. 그러면 내부 조인은 전혀 존재하지 않는 회사를 필터링합니다.