查找具有多个列的数据表中的重复项,只有两个列除外
本文关键字:两个 数据表 查找 | 更新日期: 2023-09-27 18:09:49
我是编码新手,并试图检查电子表格中的重复行。电子表格有50列,除了两列之外,每一列都要进行比较。如果行重复,则将它们合并为一行,并对列REQNUM和AUTHNUM中的金额求和。我发现的大多数示例都使用"字段("列名")"。因为有大量的列,我想使用一个变量来排除比较中不需要的两个。
例子:
之前。点表示更多列
COL1 | COL2 | COL3 |…| REQNUM | AUTHNUM
:-----: |:-----: |:----: |…|:----------: |:-----------: |....
X | y | z |…| 1 | 1
X | y | z |…| 2 | 3
COL1 | COL2 | COL3 |…| REQNUM | AUTHNUM
------- | ------ | ------ |…|------------ |------------ |....
X | y | z |…| 3 | 4
这是我的代码,它似乎很接近,但不完全正确。我期望的结果只是重复的行,所以稍后我可以通过foreach来运行它,它将求和并删除额外的行。卓罗给了我想要的专栏。(感谢Linq排除一列)。当我尝试在我的查询中使用这个变量时,我没有得到结果,如果我删除"g.c count()> 1",我得到所有的行,它们缺少两列。我希望在结果中保留所有这两列,而不必稍后再将它们添加回来。
var dtRow = dtExcel.Columns.Cast<DataColumn>().Where(c => c.ColumnName != "REQNUM" && c.ColumnName != "AUTHNUM").ToList();
var checkExcel = dtExcel.Rows.Cast<DataRow>()
.GroupBy(x => dtRow.Select(c => x[c]))
.Where(g => g.Count() > 1)
.Select(gr => gr);
//.CopyToDataTable();
感谢Ken的帮助。这对我所需要的非常有效。我使用了groupby子句,这样我就可以将副本合并到一行中,并添加数字字段。还可以通过创建一个我在IF语句中使用的键来分组。
var dtRow = dtExcel.Columns.Cast<DataColumn>().Where(c => c.ColumnName != "REQNUM" && c.ColumnName != "AUTHNUM").ToList();
var excelDup = dtExcel.Rows.Cast<DataRow>()
.GroupBy(x => String.Join("", dtRow.Select(c => x[c])))
.Select(g =>
{
var row = g.First();
row.SetField("REQNUM", g.Sum(x => x.Field<double>("REQNUM")));
row.SetField("AUTHNUM", g.Sum(x => x.Field<double>("AUTHNUM")));
return row;
})
.CopyToDataTable();
我还使用了where子句来创建一个用于数据流比较的变量,不需要键。//创建除3列外的所有列的变量。它将用于下一个查询var dtExcelRow = dtExcel。列.Cast()。Where(c => c. columnname != "TITLE" &&= "REQSTR" &&c.ColumnName != "AUTHSTR").ToList();var dtListRow = dtList。列.Cast()。Where(c => c. columnname != "TITLE" &&= "REQSTR" &&c.ColumnName != "AUTHSTR").ToList();
// Querys create datarow list for compare
IEnumerable<DataRow> eRow = dtExcel.AsEnumerable()
.Where(w => dtExcelRow.Select(c => w[c]).Any())
.Select(x => x);
IEnumerable<DataRow> lRow = dtList.AsEnumerable()
.Where(w => dtListRow.Select(c => w[c]).Any())
.Select(x => x);
// 1st compare gets list of new records that have changes or are new. 2nd is list of old records being change.
var newRecords = eRow.AsEnumerable().Except(lRow.AsEnumerable(), DataRowComparer.Default);
var oldRecords = lRow.AsEnumerable().Except(eRow.AsEnumerable(), DataRowComparer.Default);
你不能仅仅把数据按dtRow.Select(c => x[c])
分组,因为它是IEnumerable
,它们可能有相同的内容,但它们仍然是不同的IEnumerable
。
如果它们是string
,您可以通过连接字符串对数据进行分组:
x => String.Join("", dtRow.Select(c => x[c]))