换行到列。记录问题

时间:2015-05-21 01:05:58

标签: c# transpose

这是我从数据库获得的表格:

 **Month        PCode         Sales**
January        001           2
January        002           1
January        003           5
February       001           6
February       002           4
February       003           2
March          001           8
March          002           10
March          003           7

我想要的结果:

**Month           001       002      003**
January           2         1        5     
February          6         4        2
March             8        10        7

到目前为止我做了什么:

private void TransposeTable(DataTable inputTable)
{
    DataTable outputTable = new DataTable();

    outputTable.Columns.Add(inputTable.Columns[0].ColumnName.ToString());

    List<string> l_month = new List<string>();

    foreach (DataRow inRow in inputTable.Rows)
    {
        if (!l_month.Contains(inRow[1].ToString())) //if PCode not found
        {
             l_month.Add(inRow[1].ToString());
             outputTable.Columns.Add(inRow[1].ToString());//PCode as column header
        }
    }
}

我已经使用上面的代码创建了表格列,现在我对如何转置销售有疑问

2 个答案:

答案 0 :(得分:1)

如果你想创建一个新的&#34; pivot&#34; DataTable,使用唯一的PCode值作为列,您只需几步即可完成此操作:

private DataTable TransposeTable(DataTable inputTable)
{
    // create output pivot table and add the "Month" column to it.
    var pivotTable = new DataTable("PivotTable");
    var srcMonthCol = inputTable.Columns["Month"];
    var salesDataType = inputTable.Columns["Sales"].DataType;
    pivotTable.Columns.Add(new DataColumn(srcMonthCol.ColumnName, srcMonthCol.DataType));

    // get unique 'PCode' values
    var uniquePeriods = inputTable.AsEnumerable()
        .Select(x => x.Field<string>("PCode"))
        .Distinct()
        .ToList();

    // Add the unique 'PCode' as columns to the pivot table
    uniquePeriods.ForEach(p => pivotTable.Columns.Add(new DataColumn(p, salesDataType)));

    // Now we have the columns for the pivot table set-up and we need
    // to get the rows, which will be grouped by month.
    var rows = inputTable.AsEnumerable()
        .GroupBy(x => x.Field<string>("Month"))
        .Select(x => {
            var mc = new object[] { x.Key, };
            var salesCols = uniquePeriods
                .Select(p => x
                    .Where(r => r.Field<string>("PCode") == p)
                    .Select(r => r["Sales"])
                    .FirstOrDefault());
            return mc.Concat(salesCols).ToArray();
        }).ToList();

    // Now we can add the rows.
    rows.ForEach(r => pivotTable.Rows.Add(r));

    // And return the result.
    return pivotTable;
}

备注

  • 如果您使用inputTable的唯一原因是作为构建数据透视表的中介,则直接在数据库中查询创建数据透视表所需的信息可能更有效。
  • 如果每个时段/每月可以有多个销售分录,则无法按预期工作,并且需要沿其中一个轴汇总销售值。

答案 1 :(得分:0)

您可以使用免费的NReco.PivotData library聚合DataTable记录并从C#构建数据透视表报告:

DataTable inputTable; // your input data
var pivotData = new PivotData(
    new string[] {"Month","PCode"},
    new SumAggregatorFactory("Sales"),
    new DataTableReader(inputTable) );

在此步骤中,您将获得内存中的多维数据集(索引器可以访问值)。 下一步是使用PivotTable类获取数据透视表:

var pvtTbl = new PivotTable(
    new[] {"Month"},   // dimension(s) used for rows
    new [] {"PCode"},  // dimension(s) used for columns
    pivotData);

之后,您可以使用pvtTbl生成数据透视表报告,只需按列进行迭代(PivotTable.ColumnKeysPivotTable.RowsKeys +按行/列索引获取单元格值,如pvtTbl[0,0])和行(您可以下载在PivotData库官方页面上生成HTML数据透视表的MVC示例。

我是这个图书馆的作者;如果您在使用它时有任何疑问,请随时问我。