2013-02-26 4 views
2

테이블을 평평하게해야하지만 까다로운 부분이 있습니다. clomuns는 동적이며 새 ID가 들어있는 새 레코드가 추가 될 때 쿼리가 작동해야합니다. 방법Oracle sql 쿼리 : 동적으로 채워진 피벗 테이블

SELECT mq.question_id 
    FROM meta_question mq, survey_question sq2 
WHERE sq2.survey_id = 1 
    AND mq.question_id = sq2.question_id 
ORDER BY page, ranked 

어떤 생각 :

SELECT * 
FROM (select qv.respnr, sq.question_id, qv.question_value 
from survey_question sq, question_values qv 
where qv.question_id = sq.question_id 
and sq.survey_id = 1 
order by qv.respnr, page, ranked) 
PIVOT (
MAX(question_value)  --<-- pivot_clause 
FOR question_id   --<-- pivot_for_clause 
IN (346 as c346,347 as c347) 
) 

나는 이런 식으로 뭔가로 IN (346 as c346,347 as c347)를 교체하려면 :

이 (이에서 정말 값의 수백입니다 간체) 내 작업 쿼리입니다 이 작업을 수행?

나는 IN이 단순히 선택 문 fileld 할 수없는 나타났습니다, 그래서이 작동하지 않습니다

IN (SELECT mq.question_id 
     FROM meta_question mq, survey_question sq2 
    WHERE sq2.survey_id = 1 
     AND mq.question_id = sq2.question_id 
    ORDER BY page, ranked) 

답변

2

이름과 SQL에있는 모든 컬럼의 유형을 컴파일 알려진해야 시간에 따라서는에 따라 열 수를 변경하려면 을 입력해야하므로 dynamic SQL을 사용해야합니다.

DECLARE 
    l_rc   SYS_REFCURSOR; 
    l_dynamic_query VARCHAR2(32000); 
BEGIN 
    FOR cc IN (SELECT mq.question_id 
       FROM meta_question mq, survey_question sq2 
       WHERE sq2.survey_id = 1 
       AND mq.question_id = sq2.question_id 
       ORDER BY page, ranked) LOOP 
     -- build dynamic query here 
    END LOOP; 
    OPEN l_rc FOR ' 
     SELECT * 
     FROM (SELECT qv.respnr, sq.question_id, qv.question_value 
       FROM survey_question sq, question_values qv 
       WHERE qv.question_id = sq.question_id 
       AND sq.survey_id = 1 
       ORDER BY qv.respnr, page, ranked) 
       PIVOT (MAX (question_value) --<-- pivot_clause 
         FOR question_id --<-- pivot_for_clause 
         IN (' || l_dynamic_query || ') 
        )'; 
    -- process l_rc (LOOP..FETCH..CLOSE) 
END; 

또한 DBMS_SQL을 사용할 수 있습니다 : 당신은 PL/SQL을 사용하는 경우 ref cursor

, 당신은 사용할 수 있습니다.

1

pivot의 열을 알아야하므로 동적 SQL을 사용하여 결과를 생성해야합니다. 나는 일반적으로 이와 유사한이 작업을 수행하기 위해 ref_cursor를 사용하여 프로 시저를 생성합니다

CREATE OR REPLACE procedure dynamic_pivot_q(p_cursor in out sys_refcursor) 
as 
    sql_query varchar2(8000) := 'select qv.respnr '; 

    begin 
     for x in (select distinct question_id, mname from meta_question order by 1) 
     loop 
      sql_query := sql_query || 
       ' , max(case when mq.question_id = '||x.question_id||' then qv.question_value else null end) as "c'||x.mname||'"'; 

       dbms_output.put_line(sql_query); 
     end loop; 

     sql_query := sql_query || ' from meta_question mq 
            left join survey_question sq 
             on mq.question_id = sq.question_id 
             and sq.survey_id = 1 
            inner join question_values qv 
             on qv.question_id = sq.question_id 
             and sq.survey_id = 1 
            group by qv.respnr'; 

     dbms_output.put_line(sql_query); 

     open p_cursor for sql_query; 
    end; 
/

이 그럼 당신은 그것을 다음과 같은 방법을 실행할 수를

variable x refcursor 
exec dynamic_pivot_q(:x) 
print x 
: ( 참고 :이 내가 두꺼비에서 사용하는 코드입니다)