2009-07-27 47 views
1

我有一個表,要轉的行列,類似透視表,但沒有總結。SQL行分列

例如,我有如下表:

Question 
--QuestionID 
--QuestionText 

Response 
--ResponseID 
--ResponseText 
--QuestionID 

基本上我希望能夠創建一個動態表是這樣的:

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 

主要的要求是我不知道在設計時問題文本將是什麼。

請可以有人幫忙 - 我拉我的頭髮:OS

基本上可以保證會有在這種情況下每個對應的問題的答覆。

+0

哪個數據庫服務器? – AakashM 2009-07-27 12:49:51

+1

這將是SQL Server。它始終是血腥的SQL Server。 – skaffman 2009-07-27 17:02:21

+0

是的,SQL Server。我做了什麼,我需要使用XML,並通過函數實現聚合 – IThasTheAnswer 2009-07-30 13:04:55

回答

7

除非您知道設計時的列數(即問題),否則您無法使用SQL(動態查詢除外)。

你應該拉你想要的數據以表格形式,然後再處理它在客戶端:

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

,或者可能是,這(在SQL Server 2005+Oracle 8i+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 

後者查詢會給你以這種形式的結果(前提是你有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 

,這是它會輸出以表格形式的數據,與rn標記該行數。

每當您看到客戶端上的rn更改時,您只需關閉<tr>並打開新窗口。

您可能放心地把每行的結果集的<td>的一個,因爲相同數量或行保證每個rn

這將返回是一個相當常見的問題。

SQL只是沒有合適的工具與列的動態數返回數據。

SQL操作上組,和列布局是一組隱式屬性。

你應該定義要在設計時得到一組的佈局,就像你在C定義varible的數據類型。

C使用嚴格定義的變量,SQL使用嚴格定義的集合。

請注意,我不是說這可能是最好的方法。這只是SQL的工作方式。

更新:

SQL Server,你可以拉HTML形式的右表從數據庫中:

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

詳情請參見我的博客此項:

0

首先使用Quassnoi的答案作爲中間結果進行分組和聚合。

只有當你不再對結果進行設置操作時才能進行交叉製表。一些SQL方言有像PIVOT,TRANSFORM或CROSSTABULATE這樣的關鍵字來實現這一點,但你最好使用XSLT。