No puedes hacerlo con SQL
(excepto con consultas dinámicas), a menos que conozca el número de columnas (es decir, preguntas) en tiempo de diseño.
Debe extraer los datos que desea en formato tabular y luego procesarlos en el lado del cliente:
SELECT *
FROM Question
LEFT OUTER JOIN
Response
ON Response.QuestionId = Question.QuestionID
o, probablemente, esto (en SQL Server 2005+
, Oracle 8i+
y 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
La última consulta le dará resultados en este formulario (siempre que tenga 4
preguntas):
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
, esto generará los datos en formato tabular, con rn
marcando el número de fila.
Cada vez que vea el rn
cambiando en el cliente, simplemente cierre <tr>
y abre uno nuevo.
Puede poner con seguridad su <td>
es uno por fila del conjunto de resultados, ya que se garantiza que se devolverá el mismo número o filas para cada rn
Esta es una pregunta bastante frecuente.
SQL
simplemente no es una herramienta adecuada para devolver datos con un número dinámico de columnas.
SQL
opera en conjuntos, y el diseño de la columna es una propiedad implícita de un conjunto.
Debe definir el diseño del conjunto que desea obtener en tiempo de diseño, al igual que define el tipo de datos de una variable en C
.
C
trabaja con variables estrictamente definidas, SQL
funciona con conjuntos estrictamente definidos.
Tenga en cuenta que no estoy diciendo que sea el mejor método posible. Es solo la forma SQL
funciona.
Actualización:
En SQL Server
, puede extraer la tabla en HTML
formulario directamente desde la base de datos:
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')
Ver esta entrada en mi blog para más detalles:
- Pivote dinámico