英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论