2009-08-05 5 views
1
다음

당신이 내 질문을 이해하는 데 도움이 코드입니다 :긴 CORRELATED 하위 쿼리를 반복하지 않으려면 어떻게해야합니까?

create table con (content_id number); 
create table mat (material_id number, content_id number, resolution number, file_location varchar2(50), file_size number); 
create table con_groups (content_group_id number, content_id number); 

insert into con values (99); 
insert into mat values (1, 99, 7, 'C:\foo.jpg', 1024); 
insert into mat values (2, 99, 2, '\\server\xyz.mov', 350000); 
insert into mat values (3, 99, 5, '\\server2\xyz.wav', 175000); 
insert into con values (100); 
insert into mat values (4, 100, 5, 'C:\bar.png', 2048); 
insert into mat values (5, 100, 3, '\\server\xyz.mov', 27400); 
insert into mat values (6, 100, 7, '\\server2\xyz.wav', 400); 

insert into con_groups values (10, 99); 
insert into con_groups values (10, 100); 

SELECT m.material_id, 
     m.content_id, 
     (SELECT max(file_location) keep (dense_rank first order by resolution desc)     
      FROM mat 
     WHERE mat.content_id = m.content_id 
     /* AND ... 
      AND ... 
      AND ... */) special_mat_file_location, 
     (SELECT max(file_size) keep (dense_rank first order by resolution desc) 
      FROM mat 
     WHERE mat.content_id = m.content_id 
     /* AND ... 
      AND ... 
      AND ... */) special_mat_file_size 
    FROM mat m 
WHERE m.material_id IN (select material_id 
          from mat 
        inner join con on con.content_id = mat.content_id 
        inner join con_groups on con_groups.content_id = con.content_id 
          where con_groups.content_group_id = 10); 

나는이 단순화 된 예라고 강조 주석 AND 연산을 넣어; 내 실제 쿼리의 하위 쿼리는 더 많은 기준과 더 복잡합니다.

내 문제는 다음과 같습니다. 두 조건 (file_location and file_size)에 대한 하위 쿼리의 모든 조건을 반복하지 않으려는 기준이 동일합니다. 기꺼이 공통 테이블 표현식 (WITH 절을 사용하여 하위 쿼리를 분해)을 사용 하겠지만 하위 쿼리에서 "WHERE mat.content_id = m.content_id"을 사용할 수 없으므로 상관 관계가있는 하위 쿼리가됩니다. WITH 절을 사용하여 상관 관계가있는 하위 쿼리를 고려할 수 없다는 것이 내 이해입니다. 같은 이유로 FROM 절에이 하위 쿼리를 인라인 뷰 (파생 테이블이라고도 함)로 넣을 수도 없습니다.

기준을 한 번 포함시키고 상관 집합 하위 쿼리를 사용하여 결과 집합에 둘 이상의 열을 주입하려면 어떻게합니까?

+0

걱정되는 텍스트 크기 또는 쿼리 성능을 쿼리하는 것입니까? – jva

+0

좋은 질문입니다. 하위 쿼리 변경 기준 (실제 가능성)이 있어야이 쿼리를 나중에 유지 관리하는 것이 걱정됩니다. 그래서 쿼리 텍스트 크기가 걱정됩니다. –

답변

1

서브 쿼리 팩터링 (오라클이 SQL Server에서 공통 테이블 식이라고 부르는 것)을 사용하십시오. 지원되는 9i + :

WITH file AS (
    SELECT t.content_id, 
     MAX(t.file_location) keep (DENSE_RANK t.first ORDER BY t.resolution DESC) 'fileLocation', 
     MAX(t.file_size) keep (DENSE_RANK t.first ORDER BY t.resolution DESC) 'fileSize' 
    FROM mat t 
GROUP BY t.content_id) 
SELECT m.material_id, 
     m.content_id, 
     f.fileLocation, 
     f.fileSize 
    FROM mat m 
    JOIN file f ON f.content_id = m.content_id 

인라인보기 재사용을위한 것입니다. 뷰를 일반화하고 JOIN 절의 다른 인스턴스에 대한 특정 필터링을 정의합니다. SELECT 절에 참여하기 위해 열을 노출해야합니다 (예 : content_id 참조).

상관 된 하위 쿼리는 JOIN으로 다시 쓰여질 수 있음을 의미합니다. 상관 관계는 JOIN 조건입니다.

Subquery Factoring에서 여러 개의보기를 정의 할 수 있습니다. 세부 정보를 입력하면 더 잘 대답 할 수 있습니다.

+0

누구나 이것이 FROM 절의 단순한 조인이 더 나은 이유를 설명 할 수 있습니까? 아니면 별도의 뷰에 하위 쿼리 논리를 두는 것입니까? – jva

+0

Re : "상관 관계가있는 하위 쿼리는 JOIN으로 다시 쓸 수 있음을 의미합니다."- 재미있는 생각입니다. 당신의 질문에 약간의 문제가 있습니다. 파일에 잘못된 테이블 이름이 있다고 했으므로 이름을 변경했습니다. 그런 다음 집계 열의 이름이 맘에 들지 않아이를 변경했습니다. 이제 content_id에 대해 "ORA-00937 : 단일 그룹 그룹 기능이 아닙니다"라는 메시지가 나타납니다. 나는 완전히 오해하고 있니? –

+0

@ jva : Google "하위 쿼리 인수 분해" –

0

나는 그것을 얻었습니다. 난 그냥 그렇게처럼 "특별한"재료의 기본 키를 잡고 다른 레이어의 주요 쿼리를 포장 할 수 있었다 :

  SELECT x.material_id, 
       x.content_id, 
       sp_m.file_location, 
       sp_m.file_size 
      FROM (SELECT m.material_id, 
         m.content_id, 
         (SELECT max(material_id) keep (dense_rank first order by resolution desc)     
          FROM mat 
          WHERE mat.content_id = m.content_id 
         /* AND ... 
          AND ... 
          AND ... */) special_mat_primary_key 
        FROM mat m 
        WHERE m.material_id IN (select material_id 
              from mat 
             inner join con on con.content_id = mat.content_id 
             inner join con_groups on con_groups.content_id = con.content_id 
              where con_groups.content_group_id = 10)) x 
LEFT OUTER JOIN mat sp_m ON sp_m.material_id = x.special_mat_primary_key; 

이 나를 어떻게 생각하는지 알려주십시오.

+0

상관 된 subselect는 리턴 된 모든 행에 대해 실행됨을의 L합니다. IN 절은 사물을 쿼리하는 다음 최악의 수행 방법입니다. 필요한 것보다 많은 정보가 포함 된 인라인보기를 만들고 있습니다. –

관련 문제