2012-03-27 119 views
1

我無法控制數據在此表中的保存方式。但是,我必須查詢表並將類似pn_id列的數據組合爲一行/記錄。查詢 - 基於行的表

例如當前數據結構如下,

enter image description here

在這裏,我們有相同的pn_id重複不同的問題ID。根據我的意見,這應該已經真正保存爲一個pn_id,然後將每個問題作爲單獨的列保存。但是,我必須恢復下面的數據作爲這樣一個記錄這個..

enter image description here

任何想法,這可怎麼辦呢?

謝謝

+0

如果Sybase簡化版,支持旋轉操作,我只是代碼它自己在C#。這並不複雜。 – phoog 2012-03-27 22:15:19

+0

在你顯示的數據中,每個pn_id都有它自己的question_ids,在question_id 152(例如)和任何其他問題之間是否有任何關係?或者,如果有300個不同的question_ids,那麼每個行需要300列,如果給定的pn_id沒有該問題ID,則爲空值?您可以使用CASE語句在任何sql中轉發,而不使用PIVOT關鍵字。 – 2012-03-27 22:27:18

+0

是的,我想要300列與空值,因爲我想從該表與其他表中的數據列中的數據,並將其顯示爲一個記錄在C#datagridview中的記錄。在這種情況下,我將檢查CASE語句的用法。但到目前爲止,發現這個鏈接,這似乎最初應該解決問題..但今晚晚些時候會花一些時間。 http://groups.google.com/group/sybase.public.sqlanywhere.general/browse_thread/thread/81792ce38b3817e2?pli=1 – MStp 2012-03-27 22:42:43

回答

2

這裏是一些僞代碼爲轉換算法。請注意,它需要掃描整個數據集兩次;還有其他一些提高效率的機會,例如,如果可以對輸入數據進行排序。另外,由於它是僞代碼,因此我沒有爲空值添加處理。

var columnNames = new HashSet<string> { "pn_id" }; 

foreach (var record in data) 
    columnNames.Add(record.question_id.ToString()); 

var table = new DataTable(); 
foreach (var name in columnNames) 
    table.Columns.Add(new DataColumn(name, typeof(string))); 

foreach (var record in data) 
{ 
    var targetRecord = CreateNewOrGetExistingRecord(table, record.pn_id); 
    targetRecord[record.question_id.ToString()] = record.char_value ?? record.date_value.ToString(); 
} 

而這裏的helper方法的草圖:

DataRow CreateNewOrGetExistingRecord(DataTable table, object primaryKeyValue) 
{ 
    var result = table.Find(primaryKeyValue); 
    if (result != null) 
     return result; 

    //add code here to create a new row, add it to the table, and return it to the caller 
} 
+0

感謝分享,我現在正在研究它。 – MStp 2012-03-28 16:13:16

2

結構很好。每個問題只有一列是沒有意義的,因爲每次添加新問題時都必須添加一個新列。

您的問題可以很容易地用PIVOT解決。看看this鏈接的解釋

+0

我不認爲PIVOT在Sybase中受支持 – Ben 2012-03-27 21:43:24

+0

只是爲了闡明數據庫是Sybase SQL Anywhere 9.01(ASA 9.01) – MStp 2012-03-27 22:01:28