C# 比较并根据多个条件分组行

huangapple go评论94阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年2月8日 17:09:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75383443.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定