我的数据格式为:
NodeName, ReadingDate, Value
NY, 5/10/2010, 5
NY, 5/11/2010, 7
TX, 5/10/2010, 8
TX, 5/11/2010, 9
...
我想将其转换为:
ReadingDate, NY, TX
5/10/2010, 5, 8
5/11/2010, 7, 9
踢球者是有一个未知数量的节点名称所以我不能硬编码那些。还有大约2000个日期和150个节点名称。
现在我创建一个数据表,我在其中对ReadingDate列进行硬编码,然后在NodeName上使用distinct来获取唯一的名称值并使用该列创建列。然后我进入并在所有ReadingDates上独一无二,并与他们一起制作唱片。所以现在我有了专栏和ReadingDates。然后我进去填写价值观。这有效,但你可以猜测它相当慢。我想知道是否有更简单,更快捷的方式来转移我拥有的数据。
这是我到目前为止所做的:
// get the data from the database
SqlDataReader rdr = cmd.ExecuteReader();
// load into a datatable for processing
DataTable tbl = new DataTable();
tbl.Load(rdr);
// add date column and a column for all NodeNames
DataTable pivotData1 = new DataTable();
pivotData1.Columns.Add("ReadingDate", typeof(DateTime));
DataView view = new DataView(tbl);
DataTable nodeNamesData = view.ToTable(true, "NodeName");
foreach (DataRow row in nodeNamesData.Rows)
{
string data = row["NodeName"].ToString();
DataColumn col = new DataColumn(data, typeof(double));
col.DefaultValue = 0;
pivotData1.Columns.Add(col);
}
// add all unique row labels
DataView dateView = new DataView(tbl);
DataTable dateData = dateView.ToTable(true, "ReadingDate");
foreach (DataRow row in dateData.Rows)
{
DataRow newRow = pivotData1.NewRow();
newRow["ReadingDate"] = row["ReadingDate"];
pivotData1.Rows.Add(newRow);
}
// fill in the rest of the row data
foreach (DataRow row in pivotData1.Rows)
{
var rowLabel = DateTime.Parse(row["ReadingDate"].ToString());
// query to get all nodes for this date
var qry = (from a in tbl.AsEnumerable()
where a.Field<DateTime>("ReadingDate") == rowLabel
select a);
// loop over and fill in the column data for this date
foreach (var r in qry)
{
double val = 0.0;
if(r["Value"].ToString() != string.Empty)
val = Convert.ToDouble(r["Value"].ToString());
string col = r.Field<string>("NodeName");
Console.WriteLine("Date = " + rowLabel + " Node = " + col + " Value = " + val);
row.SetField<double>(col, val);
}
}
答案 0 :(得分:1)
步骤1:获取所有节点名称的列表(SELECT DISTINCT NodeName FROM myTable
)。
步骤2:将它们放在括号中并创建一个逗号分隔的字符串:[NY], [TX], ...
。
步骤3:使用此字符串构造SQL Server PIVOT statement,返回所需的数据集。
注意:由于节点名称将成为SQL语句的一部分,因此请务必清理它们以避免SQL注入。 (不幸的是,在这里使用SQL参数不是一个选项,因为节点名称实际上成为列名。)