行到列转置。记录问题
row to column Transposed. issue with the record
这是我的 table 我从数据库中得到的:
**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
}
}
}
我已经使用上面的代码创建了 table 列,现在我遇到了如何转置销售额的问题
如果您想创建一个新的 "pivot" 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
的唯一原因是作为构建数据透视表的中介 table,直接查询数据库以获取创建数据透视表所需的信息可能更有效.
- 如果每个期间/每个月可以有多个销售条目,这将不会按预期工作,并且需要沿这些轴之一求和销售值。
您可以使用免费的 C# NReco.PivotData library:
汇总 DataTable 记录并构建数据透视表 table 报告
DataTable inputTable; // your input data
var pivotData = new PivotData(
new string[] {"Month","PCode"},
new SumAggregatorFactory("Sales"),
new DataTableReader(inputTable) );
在此步骤中,您将获得内存中的多维数据集(值可以通过索引器访问)。
下一步是使用数据透视表 class:
获取数据透视表 table
var pvtTbl = new PivotTable(
new[] {"Month"}, // dimension(s) used for rows
new [] {"PCode"}, // dimension(s) used for columns
pivotData);
之后,您可以使用 pvtTbl 生成数据透视表 table 报告,只需按列迭代(PivotTable.ColumnKeys
、PivotTable.RowsKeys
+ 通过 row/column 索引获取单元格值,例如 pvtTbl[0,0]
) 和行(您可以在 PivotData 库官方页面上下载生成 HTML pivot table 的 MVC 示例)。
我是这个图书馆的作者;如果您在使用它时遇到任何困难,请随时问我。
这是我的 table 我从数据库中得到的:
**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
}
}
}
我已经使用上面的代码创建了 table 列,现在我遇到了如何转置销售额的问题
如果您想创建一个新的 "pivot" 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
的唯一原因是作为构建数据透视表的中介 table,直接查询数据库以获取创建数据透视表所需的信息可能更有效. - 如果每个期间/每个月可以有多个销售条目,这将不会按预期工作,并且需要沿这些轴之一求和销售值。
您可以使用免费的 C# NReco.PivotData library:
汇总 DataTable 记录并构建数据透视表 table 报告DataTable inputTable; // your input data
var pivotData = new PivotData(
new string[] {"Month","PCode"},
new SumAggregatorFactory("Sales"),
new DataTableReader(inputTable) );
在此步骤中,您将获得内存中的多维数据集(值可以通过索引器访问)。 下一步是使用数据透视表 class:
获取数据透视表 tablevar pvtTbl = new PivotTable(
new[] {"Month"}, // dimension(s) used for rows
new [] {"PCode"}, // dimension(s) used for columns
pivotData);
之后,您可以使用 pvtTbl 生成数据透视表 table 报告,只需按列迭代(PivotTable.ColumnKeys
、PivotTable.RowsKeys
+ 通过 row/column 索引获取单元格值,例如 pvtTbl[0,0]
) 和行(您可以在 PivotData 库官方页面上下载生成 HTML pivot table 的 MVC 示例)。
我是这个图书馆的作者;如果您在使用它时遇到任何困难,请随时问我。