英文:
C# Compare and Group Rows Based on Multiple Conditions
问题
给定一个包含以下行的数据表。
SHOPID ITEMID OLD_BATCHNO NEW_BATCHNO OLD_QTY NEW_QTY
SHOP01 ITEM01 BATCH0001 1
SHOP01 ITEM01 BATCH0001 1
SHOP02 ITEM02 BATCH0002 2
SHOP02 ITEM02 BATCH0002 3
SHOP03 ITEM03 BATCH0003 4
SHOP03 ITEM03 BATCH0003 5
SHOP04 ITEM04 BATCH0004 4
SHOP05 ITEM05 BATCH0005 5
预期结果:
SHOPID ITEMID OLD_BATCHNO NEW_BATCHNO OLD_QTY NEW_QTY
SHOP02 ITEM02 BATCH0002 BATCH0002 2 3
SHOP03 ITEM03 BATCH0003 BATCH0003 4 5
SHOP04 ITEM04 BATCH0004 4
SHOP05 ITEM05 BATCH0005 5
我想提取满足以下条件的所有行:
- 匹配的 SHOPID
- 并且
- 匹配的 ITEMID
- 并且
- 没有匹配的 [OLD_BATCHNO - NEW_BATCHNO]
- 或
- 匹配的 [OLD_BATCHNO - NEW_BATCHNO],但没有匹配的 [OLD_QTY - NEW_QTY]
英文:
Given a datatable with the following rows.
SHOPID ITEMID OLD_BATCHNO NEW_BATCHNO OLD_QTY NEW_QTY
SHOP01 ITEM01 BATCH0001 1
SHOP01 ITEM01 BATCH0001 1
SHOP02 ITEM02 BATCH0002 2
SHOP02 ITEM02 BATCH0002 3
SHOP03 ITEM03 BATCH0003 4
SHOP03 ITEM03 BATCH0003 5
SHOP04 ITEM04 BATCH0004 4
SHOP05 ITEM05 BATCH0005 5
Expected Result:
SHOPID ITEMID OLD_BATCHNO NEW_BATCHNO OLD_QTY NEW_QTY
SHOP02 ITEM02 BATCH0002 BATCH0002 2 3
SHOP03 ITEM03 BATCH0003 BATCH0003 4 5
SHOP04 ITEM04 BATCH0004 4
SHOP05 ITEM05 BATCH0005 5
I want to fetch all rows that meets the following condition:
- Matched SHOPID
- and
- Matched ITEMID
- and
- No match of [OLD_BATCHNO - NEW_BATCHNO]
- or
- Matched [OLD_BATCHNO - NEW_BATCHNO] but no match of [OLD_QTY - NEW_QTY]
答案1
得分: 1
根据您的要求,以下是代码部分的中文翻译:
您能发布一些您已经尝试的代码吗?
虽然我不太清楚您如何读取数据,但根据您的`linq`标签,我猜测您可以访问类。
根据对您的代码的一些假设,我会这样做:
```csharp
var newValues = new List<Value>();
var groupBy = values.GroupBy(x=>$"{x.SHOPID}{x.ITEMID}");
foreach(var group in groupBy){
var oldRow = group.First(x=> x.NEW_BATCHNO == "");
var newRow = group.First(x=> x.OLD_BATCHNO == "");
newValues.Add(new Value(){
SHOPID = oldRow.SHOPID,
ITEMID = oldRow.ITEMID,
OLD_BATCHNO = oldRow.OLD_BATCHNO,
NEW_BATCHNO = newRow.NEW_BATCHNO,
OLD_QTY = oldRow.NEW_BATCHNO,
NEW_QTY = newRow.NEW_BATCHNO,
};
}
return newValues;
英文:
Can you post some code of what you have tried so far?
Without having much an idea of how do you read your data, but based on your linq
tag, I would guess that you have access to classes.
Based on some assumptions about your code, I would do something like
var newValues = new List<Value>();
var groupBy = values.GroupBy(x=>$"{x.SHOPID}{x.ITEMID}");
foreach(var group in groupBy){
var oldRow = group.First(x=> x.NEW_BATCHNO == "");
var newRow = group.First(x=> x.OLD_BATCHNO == "");
newValues.Add(new Value(){
SHOPID = oldRow.SHOPID,
ITEMID = oldRow.ITEMID,
OLD_BATCHNO = oldRow.OLD_BATCHNO,
NEW_BATCHNO = newRow.NEW_BATCHNO,
OLD_QTY = oldRow.NEW_BATCHNO,
NEW_QTY = newRow.NEW_BATCHNO,
};
}
return newValues;
答案2
得分: 1
尝试这个,我试图编写一个简单的查询。
var result = datatable
.Where(d => (d.SHOPID, d.ITEMID)
== (datatable.FirstOrDefault(dd => dd.OLD_BATCHNO == dd.NEW_BATCHNO)
?? new { SHOPID = default(string), ITEMID = default(string) }))
.Where(d => d.OLD_BATCHNO == null || d.OLD_BATCHNO != d.NEW_BATCHNO || d.OLD_QTY != d.NEW_QTY);
这是您提供的代码的翻译部分。
英文:
Try this, I try to write a simple query.
var result = datatable
.Where(d => (d.SHOPID, d.ITEMID)
== (datatable.FirstOrDefault(dd => dd.OLD_BATCHNO == dd.NEW_BATCHNO)
?? new { SHOPID = default(string), ITEMID = default(string) }))
.Where(d => d.OLD_BATCHNO == null || d.OLD_BATCHNO != d.NEW_BATCHNO || d.OLD_QTY != d.NEW_QTY);
答案3
得分: 1
以下是翻译好的内容:
groupedItems
对象满足了_匹配的SHOPID_和_匹配的ITEMID_要求。
filteredGroupedItems
对象满足了以下两个要求中的任意一个要求:
- [OLD_BATCHNO - NEW_BATCHNO]没有匹配
- (匹配[OLD_BATCHNO - NEW_BATCHNO]但)[OLD_QTY - NEW_QTY]没有匹配
resultingItems
对象是每个筛选分组的“合并”项目的集合。
根据您的示例输入,相应的输出如下:
SHOP02 ITEM02 BATCH0002 BATCH0002 2 3
SHOP03 ITEM03 BATCH0003 BATCH0003 4 5
SHOP04 ITEM04 BATCH0004 4
SHOP05 ITEM05 BATCH0005 5
示例演示 链接在这里。
英文:
If the rows in your datatable are of type Item
and the rows are collected in a List<Item> items
, this should be one possible approach:
var groupedItems = items
.GroupBy(item => item.SHOPID + item.ITEMID);
var filteredGroupedItems = groupedItems
.Where(gr =>
gr
.Select(item => item.OLD_BATCHNO)
.Intersect(gr.Select(item => item.NEW_BATCHNO))
.All(string.IsNullOrEmpty) ||
gr
.Select(item => item.OLD_QTY)
.Intersect(gr.Select(item => item.NEW_QTY))
.All(qty => !qty.HasValue));
var resultingItems = filteredGroupedItems
.Select(gr => new Item
(
gr.First().SHOPID,
gr.First().ITEMID,
gr.FirstOrDefault(item => !string.IsNullOrEmpty(item.OLD_BATCHNO))?.OLD_BATCHNO,
gr.FirstOrDefault(item => !string.IsNullOrEmpty(item.NEW_BATCHNO))?.NEW_BATCHNO,
gr.FirstOrDefault(item => item.OLD_QTY.HasValue)?.OLD_QTY,
gr.FirstOrDefault(item => item.NEW_QTY.HasValue)?.NEW_QTY
))
.ToList();
> The groupedItems
object fulfills the Matched SHOPID and Matched ITEMID requirement.
> The filteredGroupedItems
object fulfills the 'one of' requirement of the following two requirements:
> - No match of [OLD_BATCHNO - NEW_BATCHNO]
> - (Matched [OLD_BATCHNO - NEW_BATCHNO] but) no match of [OLD_QTY - NEW_QTY]
> The resultingItems
objects is a collection of the 'merged' items of each filtered grouping.
Given your example input, the corresponding output is as follows:
SHOP02 ITEM02 BATCH0002 BATCH0002 2 3
SHOP03 ITEM03 BATCH0003 BATCH0003 4 5
SHOP04 ITEM04 BATCH0004 4
SHOP05 ITEM05 BATCH0005 5
Example fiddle here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论