我有一个DataTable,如下所示,
Company Manager Location Count1 Count2 Count3
------------ ------------- ------------- ----------- ---------- --------
C1 Mgr LocName 1 0 0
C1 Mgr LocName 0 3 0
C1 Mgr LocName 0 0 7
C2 Mgr2 LocName2 0 0 5
但是,我想将此表显示为
Company Manager Location Count1 Count2 Count3
------------ ------------- ------------- ----------- ---------- --------
C1 Mgr LocName 1 3 7
C2 Mgr2 LocName2 0 0 5
任何人都可以帮助我...... 谢谢你。
答案 0 :(得分:2)
按三列(公司,经理,位置)对行进行分组,并计算计数字段的总和:
var query = from r in table.AsEnumerable()
group r by new {
Company = r.Field<string>("Company"),
Manager = r.Field<string>("Manager"),
Location = r.Field<string>("Location")
} into g
select new {
g.Key.Company,
g.Key.Manager,
g.Key.Location,
Count1 = g.Sum(r => r.Field<int>("Count1"),
Count2 = g.Sum(r => r.Field<int>("Count2"),
Count3 = g.Sum(r => r.Field<int>("Count3")
};
使用自定义CopyToDataTable()
方法为自定义类型创建新的DataTable
(如果您需要DataTable
)来自此查询:
DataTable result = query.CopyToDataTable();
如果可以在服务器端使用Linq to Sql进行分组,那么查询将如下所示:
var query = from x in db.TableName
group r by new {
x.Company,
x.Manager,
x.Location
} into g
select new {
g.Key.Company,
g.Key.Manager,
g.Key.Location,
Count1 = g.Sum(x => x.Count1),
Count2 = g.Sum(x => x.Count2),
Count3 = g.Sum(x => x.Count3)
};
在这种情况下,您将避免在客户端上下载所有数据和计算。
答案 1 :(得分:1)
您可以使用Enumerable.GroupBy
+ Sum
:
var companyGroups = tblCompany.AsEnumerable()
.GroupBy(row => new {
Company = row.Field<string>("Company"),
Manager = row.Field<string>("Manager"),
Location = row.Field<string>("Location"),
});
// creates an empty DataTable with the same columns:
var merge = tblCompany.Clone();
foreach(var companyGroup in companyGroups)
{
merge.Rows.Add(
companyGroup.Key.Company,
companyGroup.Key.Manager,
companyGroup.Key.Location,
companyGroup.Sum(row => row.Field<int>("Count1")),
companyGroup.Sum(row => row.Field<int>("Count2")),
companyGroup.Sum(row => row.Field<int>("Count3")));
}
您的样本数据会产生所需的结果:
var tblCompany = new DataTable();
tblCompany.Columns.Add("Company", typeof(string));
tblCompany.Columns.Add("Manager", typeof(string));
tblCompany.Columns.Add("Location", typeof(string));
tblCompany.Columns.Add("Count1", typeof(int));
tblCompany.Columns.Add("Count2", typeof(int));
tblCompany.Columns.Add("Count3", typeof(int));
tblCompany.Rows.Add("C1", "Mgr", "LocName", 1, 0, 0);
tblCompany.Rows.Add("C1", "Mgr", "LocName", 1, 3, 0);
tblCompany.Rows.Add("C1", "Mgr", "LocName", 0, 0, 7);
tblCompany.Rows.Add("C2", "Mgr2", "LocName2", 0, 0, 5);
如果您想要获取每个组的第一个值!= 0
:
foreach (var companyGroup in companyGroups)
{
merge.Rows.Add(
companyGroup.Key.Company,
companyGroup.Key.Manager,
companyGroup.Key.Location,
companyGroup
.Select(row => row.Field<int>("Count1"))
.Where(i => i != 0)
.FirstOrDefault(),
companyGroup
.Select(row => row.Field<int>("Count2"))
.Where(i => i != 0)
.FirstOrDefault(),
companyGroup
.Select(row => row.Field<int>("Count3"))
.Where(i => i != 0)
.FirstOrDefault());
}
为了完整起见,如果您需要修改原始表而不是创建新表:
foreach (var companyGroup in companyGroups)
{
// modify just the first row of each group,
// all others will be removed after the merge
DataRow first = companyGroup.First();
first.SetField("Count1", companyGroup.Sum(row => row.Field<int>("Count1")));
first.SetField("Count2", companyGroup.Sum(row => row.Field<int>("Count2")));
first.SetField("Count3", companyGroup.Sum(row => row.Field<int>("Count3")));
foreach (DataRow other in companyGroup.Skip(1))
tblCompany.Rows.Remove(other);
}