2012-03-27 123 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