Bạn không thể làm điều đó với SQL
(ngoại trừ với các truy vấn động), trừ khi bạn biết số lượng cột (i. e. câu hỏi) trong thời gian thiết kế.
Bạn nên lấy dữ liệu bạn muốn ở định dạng bảng và sau đó xử lý nó ở phía máy khách:
SELECT *
FROM Question
LEFT OUTER JOIN
Response
ON Response.QuestionId = Question.QuestionID
hoặc, có thể, cái này (trong SQL Server 2005+
, Oracle 8i+
và 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
Truy vấn sau sẽ cung cấp cho bạn kết quả trong biểu mẫu này (miễn là bạn có 4
câu hỏi):
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
, đây là nó sẽ xuất dữ liệu ở dạng bảng, với rn
đánh dấu số hàng.
Mỗi lần bạn nhìn thấy rn
thay đổi trên máy khách, bạn chỉ cần đóng <tr>
và mở cái mới.
Bạn có thể đặt <td>
của mình một cách an toàn là một cho mỗi hàng tập kết quả, vì cùng một số hoặc các hàng được đảm bảo trả về cho mỗi rn
Đây là một câu hỏi thường gặp.
SQL
chỉ không phải là một công cụ phù hợp để trả về dữ liệu với số lượng cột động.
SQL
hoạt động trên tập hợp và bố cục cột là thuộc tính ngầm định của tập hợp.
Bạn nên xác định bố cục của tập hợp mà bạn muốn có trong thời gian thiết kế, giống như bạn xác định kiểu dữ liệu của một biến thể trong C
.
C
hoạt động với các biến được xác định nghiêm ngặt, SQL
hoạt động với các tập hợp được xác định nghiêm ngặt.
Lưu ý rằng tôi không nói đó là phương pháp tốt nhất có thể. Đó chỉ là cách SQL
hoạt động.
Cập nhật:
Trong SQL Server
, bạn có thể kéo bảng trong HTML
biểu mẫu ngay từ cơ sở dữ liệu:
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')
Xem mục này trong blog của tôi để biết thêm chi tiết:
- Trục động