我有一个具有以下结构的DT
unit | value | date
-------------------------
A | 2 | 01-01-2000
B | 3 | 01-01-2000
A | 4 | 02-01-2000
我想将其转换为以下
| A | B
---------------------------
01-01-2000 | 2 | 3
02-01-2000 | 4 |
实现这一目标的最快方法是什么?
编辑: 我已经为pivot实现了一个函数,它给了我以下内容:
| A | B | A
--------------------------------------
value | 2 | 3 | 4
date |01-01-2000|01-01-2000|02-01-2000
但在这种情况下,我缺少按列分组。
最快'我的意思是可能是实现这个的最短代码(LINQ?)。或者也许可以在同一个查询中同时实现数据透视?
答案 0 :(得分:1)
试试这个
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
dt.Columns.Add("unit", typeof(string));
dt.Columns.Add("value", typeof(int));
dt.Columns.Add("date", typeof(DateTime));
dt.Rows.Add(new object[] { "A",2, DateTime.Parse("01-01-2000")});
dt.Rows.Add(new object[] { "B",3, DateTime.Parse("01-01-2000")});
dt.Rows.Add(new object[] { "A",4, DateTime.Parse("02-01-2000")});
string[] uniqueUnits = dt.AsEnumerable().Select(x => x.Field<string>("unit")).Distinct().ToArray();
DataTable dt1 = new DataTable();
dt1.Columns.Add("date", typeof(DateTime));
foreach (string unit in uniqueUnits)
{
dt1.Columns.Add(unit, typeof(int));
}
var groups = dt.AsEnumerable().GroupBy(x => x.Field<DateTime>("date"));
foreach (var group in groups)
{
DataRow newRow = dt1.Rows.Add();
foreach (DataRow row in group)
{
newRow["date"] = group.Key;
newRow[row.Field<string>("unit")] = row.Field<int>("value");
}
}
}
}
}
答案 1 :(得分:0)
它有更多的代码行,但也可以只用一个循环来完成:
DataTable dt1 = new DataTable();
dt1.Columns.Add(new DataColumn("unit",typeof(string)));
dt1.Columns.Add(new DataColumn("value",typeof(int)));
dt1.Columns.Add(new DataColumn("date",typeof(DateTime)));
dt1.Rows.Add(new object[] { "A", 2, DateTime.Parse("01-01-2000") });
dt1.Rows.Add(new object[] { "B", 3, DateTime.Parse("01-01-2000") });
dt1.Rows.Add(new object[] { "A", 4, DateTime.Parse("02-01-2000") });
DataTable dt2 = new DataTable();
dt2.Columns.Add(new DataColumn("date", typeof(DateTime)));
dt2.PrimaryKey = new DataColumn[] { dt2.Columns["date"], };
List<string> cols = new List<string>();
List<DateTime> ds = new List<DateTime>();
foreach (DataRow dr1 in dt1.Rows)
{
string unit = dr1["unit"].ToString();
if (!cols.Contains(unit))
{
dt2.Columns.Add(new DataColumn(unit, typeof(int)));
cols.Add(unit);
}
DateTime pkDate = (DateTime)dr1["date"];
if (!ds.Contains(pkDate))
{
ds.Add(pkDate);
DataRow dr = dt2.NewRow();
dr["date"] = dr1["date"];
dr[unit] = dr1["value"];
dt2.Rows.Add(dr);
}
else
{
dt2.Rows.Find(pkDate)[unit] = dr1["value"];
}
}