2009-07-27 3 views
1

테이블을 가지고 있고 피벗 테이블과 비슷하지만 요약하지 않고 열을 행으로 조 변경하려고합니다. 예를 들어SQL 행을 열

나는 다음과 같은 테이블이 있습니다

Question 
--QuestionID 
--QuestionText 

Response 
--ResponseID 
--ResponseText 
--QuestionID 

은 기본적으로 내가 좋아하는 동적 테이블 뭔가 만들 수 있도록하려면 :

Question 1 Text | Question 2 Text | Question 3 Text 
--------------------------------------------------- 
Response 1.1 Text | Response Text 1.2 | Response 1.3 
Response 2.1 Text | Response Text 2.2 | Response 2.3 
Response 3.1 Text | Response Text 3.2 | Response 3.3 
Response 4.1 Text | Response Text 4.2 | Response 4.3 

을 주요 요구 사항은 내가 모르는 것 디자인 타임에 질문 텍스트가 될 것입니다.

하시기 바랍니다 할 수있는 사람의 도움 - 나는 내 머리를 잡아 당겨 오전 :

OS

을 본질적으로이 시나리오의 각 해당 질문에 대한 응답이있을 것이라는 점을 보장 할 수있다.

+0

어떤 데이터베이스 서버입니까? – AakashM

+1

SQL Server가됩니다. 항상 피 묻은 SQL Server입니다. – skaffman

+0

예, SQL Server. XML을 사용하는 데 필요한 일을하고 함수를 통해 집계를 수행합니다. – IThasTheAnswer

답변

7

디자인 타임에 열 수 (즉, 질문)를 알지 못하면 SQL (동적 쿼리 제외)으로는 수행 할 수 없습니다.

당신은 표 형식으로 원하는 데이터를 가져 다음 클라이언트 측에서이를 처리해야합니다, 아마,

SELECT * 
FROM Question 
LEFT OUTER JOIN 
     Response 
ON  Response.QuestionId = Question.QuestionID 

또는이 (SQL Server 2005+, Oracle 8i+PostgreSQL 8.4+에서) :

SELECT * 
FROM (
     SELECT q.*, ROW_NUMBER() OVER (ORDER BY questionID) AS rn 
     FROM Question q 
     ) q 
LEFT OUTER JOIN 
     (
     SELECT r.*, ROW_NUMBER() OVER (PARTITION BY questionID ORDER BY ResponseID) AS rn 
     FROM Response r 
     ) r 
ON  r.QuestionId = q.QuestionID 
     AND q.rn = r.rn 
ORDER BY 
     q.rn, q.QuestionID 

후자의 쿼리는이 양식의 결과를 제공합니다 (4 개의 질문이 제공된 경우).

rn  question  response 
---   ---   --- 
1  Question 1 Response 1.1 
1  Question 2 Response 2.1 
1  Question 3 Response 3.1 
1  Question 4 Response 4.1 
2  Question 1 Response 1.2 
2  Question 2 Response 2.2 
2  Question 3 NULL 
2  Question 4 Response 4.2 
3  Question 1 NULL 
3  Question 2 NULL 
3  Question 3 Response 3.3 
3  Question 4 NULL 

의 경우 행 번호를 표시하는 rn으로 표 형식으로 데이터를 출력합니다.

rn이 클라이언트에서 변경 될 때마다 <tr>을 닫고 새 메시지를 엽니 다. 같은 번호 또는 행이 각 rn

이 반환이 보장되기 때문에

당신은 안전하게, 결과 집합 행 당 <td>의 하나를 넣을 수 있습니다 것은 꽤 자주 질문을합니다.

SQL 역동적 인 수의 열로 데이터를 반환하는 데 적합한 도구가 아닙니다.

SQL은 집합에서 작동하고 열 레이아웃은 집합의 암시 적 속성입니다.

가변의 데이터 유형을 C에 정의하는 것처럼 디자인 타임에 가져올 세트의 레이아웃을 정의해야합니다.

C은 엄격하게 정의 된 변수와 함께 작동하며, SQL은 엄격하게 정의 된 집합과 함께 작동합니다.

나는 이것이 가능한 최선의 방법이라는 것을 말하는 것이 아니라는 점에 유의하십시오. 그것은 단지 SQL의 작동 방식입니다.

업데이트 :

SQL Server에서 바로 데이터베이스에서 HTML 형태의 테이블을 뽑을 수 :

    :

    WITH a AS 
         (
         SELECT a.*, ROW_NUMBER() OVER (PARTITION BY question_id ORDER BY id) AS rn 
         FROM answer a 
         ), 
         rows AS (
         SELECT ROW_NUMBER() OVER (ORDER BY id) AS rn 
         FROM answer a 
         WHERE question_id = 
           (
           SELECT TOP 1 question_id 
           FROM answer a 
           GROUP BY 
             question_id 
           ORDER BY 
             COUNT(*) DESC 
           ) 
         ) 
    SELECT (
         SELECT COALESCE(a.value, '') 
         FROM question q 
         LEFT JOIN 
           a 
         ON  a.rn = rows.rn 
           AND a.question_id = q.id 
         FOR XML PATH ('td'), TYPE 
         ) AS tr 
    FROM rows 
    FOR XML PATH(''), ROOT('table') 
    

    자세한 내용에 대한 내 블로그에서이 항목을 참조하십시오

  • Dynamic pivot
+0

답장을 보내 주셔서 감사합니다. 나는 그룹화 및 집계를 수행하기 위해 테이블로 끝나는 솔루션을 찾고자합니다. 열이 사용자 중심 데이터를 기반으로하기 때문에 디자인 타임에 열 수를 알 수 없습니다. – IThasTheAnswer

+0

@Tunic : 게시 업데이트 참조 – Quassnoi

+0

감사합니다. XSLT를 사용하여 데이터를 처리하기 때문에 이미 클라이언트 측에서 비슷한 솔루션을 얻었습니다. 문제는 궁극적으로 결과 조합을 알아야하기 때문에 SQL의 테이블 형식 데이터를 그룹화하고 집계 할 수있게하려는 이유 – IThasTheAnswer

0

Quassnoi의 대답을 중간 결과로 사용하여 먼저 그룹화하고 집계하십시오.

크로스 탭은 더 이상 결과에 대해 집합 지향 연산을 수행하지 않을 경우에만 수행해야합니다. 일부 SQL Dialect는 PIVOT, TRANSFORM 또는 CROSSTABULATE와 같은 키워드를 사용하여이를 수행하지만 XSLT를 사용하는 것이 더 나을 것입니다.

+0

문제는 - 크로스 탭의 결과를 집계 할 때 어떤 일이 발생합니까? 지금까지 가지고있는 유일한 방법은 필드를 concatinated 문자열로 바꾸는 함수를 사용하는 것입니다. 매우 더럽습니다. – IThasTheAnswer