복붙노트

[SQL] 결과는 SQL 전치하는 하나의 열은 복수 열로 이동되도록

SQL

결과는 SQL 전치하는 하나의 열은 복수 열로 이동되도록

나는 특정 형식의 설문 조사에 대한 테이블에서 데이터를 얻기 위해 노력하고있어. 그러나 내 모든 시도 때문에 너무 많은 DB에 너무 무거운 / 조인의 DB를 손에 보인다.

내 데이터는 다음과 같습니다 :

id, user, question_id, answer_id, 
1,   1,   1,           1
3,   1,   3,           15
4,   2,   1,           2
5,   2,   2,           12
6,   2,   3,           20

이 약 25 행이며, 각 사용자는 30 행에 대해이있다. 내가 좋아하는 모습에 결과를 원하는 :

user0, q1, q2,   q3 
1,     1,  NULL, 15
2,     2,  12,   20 

각 사용자는 각 답변에 대한 별도의 열이 결과의 한 행, 각을 갖도록.

나는 포스트 그레스를 사용하고 있지만 내가 포스트 그레스로 번역 할 수 있기 때문에 모든 SQL 언어로 답변 주시면 감사하겠습니다.

편집 : 나는 또한 사용자가 사용자 1 분기 위의 예에서 즉, 질문에 대답하지 처리 할 수 ​​있어야합니다.

해결법

  1. ==============================

    1.다음 데모를 고려 :

    다음 데모를 고려 :

    CREATE TEMP TABLE qa (id int, usr int, question_id int, answer_id int);
    INSERT INTO qa VALUES
     (1,1,1,1)
    ,(2,1,2,9)
    ,(3,1,3,15)
    ,(4,2,1,2)
    ,(5,2,2,12)
    ,(6,2,3,20);
    
    SELECT *
    FROM   crosstab('
        SELECT usr::text
              ,question_id
              ,answer_id
        FROM qa
        ORDER BY 1,2')
     AS ct (
         usr text
        ,q1 int
        ,q2 int
        ,q3 int);
    

    결과:

     usr | q1 | q2 | q3
    -----+----+----+----
     1   |  1 |  9 | 15
     2   |  2 | 12 | 20
    (2 rows)
    

    사용자가 예약 된 단어입니다. 열 이름으로 사용하지 마십시오! 나는 USR에 이름.

    당신은 함수 크로스 탭을 제공하는 추가 모듈 tablefunc ()를 설치해야합니다. 이 작업은 데이터베이스에 따라 엄격합니다. PostgreSQL의 9.1에서 간단히 할 수 있습니다

    CREATE EXTENSION tablefunc;
    

    이전 버전의 경우 당신은 당신의 contrib 디렉토리에 제공되는 쉘 스크립트를 실행합니다. 데비안에서 PostgreSQL의 8.4에 대한, 그 것이다 :

    psql mydb -f /usr/share/postgresql/8.4/contrib/tablefunc.sql
    
  2. ==============================

    2.Erwins 응답은 사용자 쇼까지에 대한 대답없는 때까지, 좋다. 난 당신이 사용자 당 하나 개의 행이있는 사용자 테이블이 .... 당신 가정을 만들려고 해요 당신은 질문 당 하나 개의 행이있는 질문에 테이블이 있습니다.

    Erwins 응답은 사용자 쇼까지에 대한 대답없는 때까지, 좋다. 난 당신이 사용자 당 하나 개의 행이있는 사용자 테이블이 .... 당신 가정을 만들려고 해요 당신은 질문 당 하나 개의 행이있는 질문에 테이블이 있습니다.

    select usr, question_id
    from users u inner join questions q on 1=1
    order by 1,
    

    이 문장은 모든 사용자 / 질문에 대한 행을 생성하고, 같은 순서 일 것이다. 하위 쿼리로를 켜고 왼쪽 데이터에 가입 ...

    select usr,question_id,qa.answer_id
    from
    (select usr, question_id
    from users u inner join questions q on 1=1
    )a
    left join qa on qa.usr = a.usr and qa.question_id = a.usr
    order by 1,2
    

    플러그가 Erwins 크로스 탭 문에 그에게 대답 신용을 제공 : P

  3. ==============================

    3.나는 하드 코딩 질문의 특정 번호를하지 않고이 문제를 처리하거나 외부 모듈 / 확장을 사용하는 진정한 동적 기능을 구현했습니다. 그것은 또한 크로스 탭보다 사용하기 훨씬 간단합니다 ().

    나는 하드 코딩 질문의 특정 번호를하지 않고이 문제를 처리하거나 외부 모듈 / 확장을 사용하는 진정한 동적 기능을 구현했습니다. 그것은 또한 크로스 탭보다 사용하기 훨씬 간단합니다 ().

    당신은 여기에서 찾을 수 있습니다 https://github.com/jumpstarter-io/colpivot

    이 특정 문제를 해결 예 :

    begin;
    
    create temp table qa (id int, usr int, question_id int, answer_id int);
    insert into qa values
     (1,1,1,1)
    ,(2,1,2,9)
    ,(3,1,3,15)
    ,(4,2,1,2)
    ,(5,2,2,12)
    ,(6,2,3,20);
    
    select colpivot('_output', $$
        select usr, ('q' || question_id::text) question_id, answer_id from qa
    $$, array['usr'], array['question_id'], '#.answer_id', null);
    
    select * from _output;
    
    rollback;
    

    결과:

     usr | 'q1' | 'q2' | 'q3' 
    -----+------+------+------
       1 |    1 |    9 |   15
       2 |    2 |   12 |   20
    (2 rows)
    
  4. from https://stackoverflow.com/questions/8490478/transposing-an-sql-result-so-that-one-column-goes-onto-multiple-columns by cc-by-sa and MIT license