我发现了link
这里的代码可以使用数据透视值和数据透视表来旋转数据表。我需要的是根据日期进行调整,并保留所有其他值列,如下所示:
Date Column1 Column2 Column3
2010 10 20 30
2011 40 50 60
在这里,我将列名称作为第一行及其在年份下的值:
2010 2011
Column1 10 40
Column2 20 50
Column3 30 60
这是我现在的代码:
DataTable Pivot(DataTable dt, DataColumn pivotColumn, DataColumn pivotValue) {
// find primary key columns
//(i.e. everything but pivot column and pivot value)
DataTable temp = dt.Copy();
temp.Columns.Remove( pivotColumn.ColumnName );
temp.Columns.Remove( pivotValue.ColumnName );
string[] pkColumnNames = temp.Columns.Cast<DataColumn>()
.Select( c => c.ColumnName )
.ToArray();
// prep results table
DataTable result = temp.DefaultView.ToTable(true, pkColumnNames).Copy();
result.PrimaryKey = result.Columns.Cast<DataColumn>().ToArray();
dt.AsEnumerable()
.Select(r => r[pivotColumn.ColumnName].ToString())
.Distinct().ToList()
.ForEach (c => result.Columns.Add(c, pivotColumn.DataType));
// load it
foreach( DataRow row in dt.Rows ) {
// find row to update
DataRow aggRow = result.Rows.Find(
pkColumnNames
.Select( c => row[c] )
.ToArray() );
// the aggregate used here is LATEST
// adjust the next line if you want (SUM, MAX, etc...)
aggRow[row[pivotColumn.ColumnName].ToString()] = row[pivotValue.ColumnName];
}
return result;
}
如何使用多个列值实现此结果?
答案 0 :(得分:1)
我认为你需要采取略微不同的方法,因为你的方式略有不同。这是一种仅使用表格和pivotColumnName
的方法。使用输入表计算出其他所有内容。
DataTable Pivot(DataTable table, string pivotColumnName)
{
// TODO make sure the table contains at least two columns
// get the data type of the first value column
var dataType = table.Columns[1].DataType;
// create a pivoted table, and add the first column
var pivotedTable = new DataTable();
pivotedTable.Columns.Add("Row Name", typeof(string));
// determine the names of the remaining columns of the pivoted table
var additionalColumnNames = table
.AsEnumerable()
.Select(x => x[pivotColumnName].ToString());
// add the remaining columns to the pivoted table
foreach (var columnName in additionalColumnNames)
pivotedTable.Columns.Add(columnName, dataType);
// determine the row names for the pivoted table
var rowNames = table.Columns
.Cast<DataColumn>()
.Select(x => x.ColumnName)
.Where(x => x != pivotColumnName);
// fill in the pivoted data
foreach (var rowName in rowNames)
{
// get the value data from the appropriate column of the input table
var pivotedData = table
.AsEnumerable()
.Select(x => x[rowName]);
// make the rowName the first value
var data = new object[] { rowName }
.Concat(pivotedData)
.ToArray();
// add the row
pivotedTable.Rows.Add(data);
}
return pivotedTable;
}
以下是我用来测试的内容:
var dateColumn = new DataColumn("Date", typeof(int));
var column1 = new DataColumn("Column1", typeof(int));
var column2 = new DataColumn("Column2", typeof(int));
var column3 = new DataColumn("Column3", typeof(int));
var table = new DataTable();
table.Columns.Add(dateColumn);
table.Columns.Add(column1);
table.Columns.Add(column2);
table.Columns.Add(column3);
table.Rows.Add(new object[] { 2010, 10, 20, 30 });
table.Rows.Add(new object[] { 2011, 40, 50, 60 });
var pivotedTable = Pivot(table, "Date");