Je kunt het niet doen met SQL
(behalve bij dynamische zoekopdrachten), tenzij u het aantal kolommen (d.w.z. vragen) in de ontwerptijd weet.
U moet de gewenste gegevens in tabelvorm ophalen en deze vervolgens aan de clientzijde verwerken:
SELECT *
FROM Question
LEFT OUTER JOIN
Response
ON Response.QuestionId = Question.QuestionID
of, waarschijnlijk, dit (in SQL Server 2005+
, Oracle 8i+
en 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
De laatste zoekopdracht geeft u resultaten in dit formulier (op voorwaarde dat u 4
. heeft vragen):
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
, dit is dat het de gegevens in tabelvorm zal uitvoeren, met rn
het rijnummer markeren.
Elke keer dat je de rn
. ziet veranderen op de client, je sluit gewoon <tr>
en open de nieuwe.
U kunt uw <td>
. veilig plaatsen 's één per resultaatsetrij, aangezien hetzelfde aantal of dezelfde rijen gegarandeerd wordt geretourneerd voor elke rn
Dit is een veelgestelde vraag.
SQL
gewoon geen juiste tool om gegevens met dynamisch aantal kolommen te retourneren.
SQL
werkt op sets en de kolomlay-out is een impliciete eigenschap van een set.
U moet de lay-out definiëren van de set die u in ontwerptijd wilt krijgen, net zoals u het datatype van een variabele definieert in C
.
C
werkt met strikt gedefinieerde variabelen, SQL
werkt met strikt gedefinieerde sets.
Merk op dat ik niet zeg dat dit de best mogelijke methode is. Het is gewoon de manier waarop SQL
werkt.
Bijwerken:
In SQL Server
, kunt u de tabel in HTML
trekken formulier rechtstreeks uit de database:
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')
Zie dit bericht in mijn blog voor meer details:
- Dynamische spil