Pergunta

Eu tenho uma tabela e quer transpor suas linhas em colunas, semelhante a uma tabela dinâmica, mas sem resumindo.

Por exemplo, eu tenho as seguintes tabelas:

Question
--QuestionID
--QuestionText

Response
--ResponseID
--ResponseText
--QuestionID

Basicamente eu quero ser capaz de criar uma tabela algo dinâmico como:

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

O requisito principal seria eu não sei no momento da concepção o que o texto da pergunta será.

Por favor, alguém pode me ajudar - Estou puxando meu cabelo para fora: oS

Essencialmente, você pode garantir que não haverá uma resposta para cada pergunta correspondente neste cenário.

Foi útil?

Solução

Você não pode fazê-lo com SQL (exceto com consultas dinâmicas), se você não sabe o número de colunas (i. E. Perguntas) em tempo de design.

Você deve puxar os dados que você quer em formato tabular e depois processá-lo no lado do cliente:

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

ou, provavelmente, este (em SQL Server 2005+, Oracle 8i+ e 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

A última consulta lhe dará resultados nesta forma (desde que você tenha perguntas 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

, isto é a saída será os dados em forma de tabela, com rn marcação do número de linha.

Cada vez que você vê o rn mudança no cliente, você apenas perto <tr> e abrir uma nova.

Você pode colocar com segurança um do seu <td> por linha de resultados, uma vez que mesmo número ou linhas é garantida a ser retornado para cada rn

Esta é completamente uma pergunta freqüente.

SQL não apenas uma ferramenta certa para retornar dados com número dinâmico de colunas.

SQL opera em sets, eo layout da coluna é uma propriedade implícita de um set.

Você deve definir o layout do conjunto que você deseja obter em tempo de design, como você define o tipo de dados de um varible em C.

C trabalha com variáveis ??estritamente definidas, obras SQL com conjuntos estritamente definidas.

Note que eu não estou dizendo que é o melhor método possível. É apenas as obras maneira SQL.

Update:

Em SQL Server, você pode puxar a mesa em forma HTML direita para fora do banco de dados:

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')

Veja esta entrada no meu blog para mais detalhes:

Outras dicas

Faça o seu agrupamento e agregação de primeira, usando a resposta de Quassnoi como um resultado intermediário.

tabulação cruzada só deve ser feito quando você está não vai estar fazendo orientada conjunto operatons sobre os resultados. Alguns dialetos SQL têm palavras-chave como pivô, transformar ou CROSSTABULATE de conseguir isso, mas você é provavelmente melhor fora de usar XSLT.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top