Você não pode fazer isso com
SQL
(exceto com consultas dinâmicas), a menos que você saiba o número de colunas (ou seja, perguntas) em tempo de design. Você deve extrair os dados desejados em formato tabular e processá-los no lado do cliente:
SELECT *
FROM Question
LEFT OUTER JOIN
Response
ON Response.QuestionId = Question.QuestionID
ou, provavelmente, isso (no
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 fornecerá resultados neste formulário (desde que você tenha
4
questões):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 é, ele produzirá os dados em formato tabular, com
rn
marcando o número da linha. Cada vez que você vê o
rn
alterando no cliente, basta fechar <tr>
e abra o novo. Você pode colocar com segurança seu
<td>
é um por linha do conjunto de resultados, pois o mesmo número ou linhas é garantido para cada rn
Esta é uma pergunta bastante frequente.
SQL
apenas não é uma ferramenta certa para retornar dados com número dinâmico de colunas. SQL
opera em conjuntos, e o layout da coluna é uma propriedade implícita de um conjunto. Você deve definir o layout do conjunto que deseja obter em tempo de design, assim como define o tipo de dados de uma variável em
C
. C
trabalha com variáveis estritamente definidas, SQL
trabalha com conjuntos estritamente definidos. Observe que não estou dizendo que é o melhor método possível. É apenas a maneira como
SQL
funciona. Atualização:
Em
SQL Server
, você pode puxar a tabela em HTML
formulário direto 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:
- Pivot dinâmico