【问题标题】:Pivot datatable c# with many value columns具有许多值列的数据透视表 C#
【发布时间】:2016-03-11 04:27:30
【问题描述】:

我找到了这个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;
}

如何使用多个列值实现此结果?

【问题讨论】:

  • 有问题吗?
  • 是的,如何使用 c# 达到预期的效果?当我现在进行旋转时,我只能使用一个值列。

标签: c# dynamic pivot


【解决方案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");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多