SQL Server 或 C# - 将相似的记录归为一组

Posted

技术标签:

【中文标题】SQL Server 或 C# - 将相似的记录归为一组【英文标题】:SQL Server or C# - group similar records into one 【发布时间】:2021-07-13 12:58:47 【问题描述】:

我们有一个记录错误的 SQL 服务器。我想从中提取一种“错误报告”,以查看给定发起者的每个错误有多少。

我可以通过从适当的表中选择并按发起者和错误分组并添加“Count(*)”来完成此操作。我正在使用 LINQ EF Core,但如果需要,可以转换为 SQL 查询来解决我的以下问题。 问题是出现“Document 2361343 failed.”、“Document 47464425 failed”等错误。

如何将所有类似的错误归为一个,例如“文档 * 失败”?

我想我可以尝试使用正则表达式,但我不知道如何将其合并到 LINQ 和/或 SQL 语句中。

理想情况下,一个通用的解决方案,也许是一种能够检测相似消息并将它们分组为一个的算法,将是理想的,但我也会满足于解决特定的“文档 * 失败”问题。

理想情况下我很想有人告诉我一种可以识别相似文本并将它们分组的算法。基本上这个正则表达式 Document .* failed 但足够聪明,可以处理任何没有硬编码的文本。所以它可以识别lala 5 yoyolala 4 yoyo 而无需我告诉它lala .* yoyo

编辑:

表格中的示例数据(跳过不相关的列):

Originator                      Error
-------------------------------------------------
Voltuas                         Record unavailable.
BonBon                          Order 47579 already shipped.
Voltuas                         Record unavailable
BizWalk                         Document 3527267 failed.
BizWalk                         Record unavailable.
Voltuas                         Order 7487 already shipped.
Gonda                           Document 78959 failed.
BizWalk                         Document 56739028 failed.

期望的输出:

Voltuas - Record unavailable - 2
Voltuas - Order * already shipped. - 1
BonBon  - Order * already shipped. - 1
BizWalk - Document * failed - 2
BizWalk - Record unavailable - 1
Gonda   - Document * failed - 1

到目前为止我所拥有的(使用最新的 EF Core):

context.Table_name.GroupBy(g => new  g.Originator, g.Error )
       .Select(x => new  Originator = x.Key.Originator, Error = x.Key.Error, Count = x.Count()).ToList();

【问题讨论】:

请向我们展示样本数据、期望的结果和您的最佳尝试。实际上,您需要更具体一些 - 有多种方法可以解决这个问题,这使得它很容易被关闭。你可以用你正在考虑的任何方式来解决它……你可以选择。 可能您可以创建一个视图并使用case 和一些like 匹配并从中聚合的通用描述替换描述。 WHERE [错误描述] LIKE'文档 % 失败' @DaleK,已编辑,而且,我不知道如何以我提到的任何方式解决它,这正是我要问的。理想情况下,我希望有人告诉我要使用的算法。 @Stu,我必须将每个此类错误都硬编码到该视图中,这将是次优的。 【参考方案1】:

一个选项可以是 GROUP BY 删除所有数字的字符串。有关如何在 SQL 中从字符串中删除数字,您可以查看Remove numbers from string sql server。

如果您在错误消息中包含可变字符串,这显然不起作用,但也许您没有。

对于实体框架Function Mappings of the Microsoft SQL Server Provider 表示支持替换。

以下是 linq to objects,但它也应该适用于数据库。

var l = new[] 
    new Originator = "Voltuas", Error = "Record unavailable.",
    new Originator = "BonBon", Error = "Order 47579 already shipped.",
    new Originator = "Voltuas", Error = "Record unavailable",
    new Originator = "BizWalk", Error = "Document 3527267 failed.",
    new Originator = "BizWalk", Error = "Record unavailable.",
    new Originator = "Voltuas", Error = "Order 7487 already shipped.",
    new Originator = "Gonda", Error = "Document 78959 failed.",
    new Originator = "BizWalk", Error = "Document 56739028 failed.",
;


var grouped = l.Select( r => new  r.Originator, Error = r.Error.Replace("0","").Replace("1","").Replace("2","").Replace("3","").Replace("4","").Replace("5","").Replace("6","").Replace("7","").Replace("8","").Replace("9",""))
    .GroupBy(g => new  g.Originator, g.Error )
    .Select(x => new  Originator = x.Key.Originator, Error = x.Key.Error, Count = x.Count())
    .ToList();

foreach (var g in grouped)

    Console.WriteLine($"g.Originator\t'g.Error' = g.Count ");

打印出来:

Voltuas 'Record unavailable.' = 1 
BonBon  'Order  already shipped.' = 1 
Voltuas 'Record unavailable' = 1 
BizWalk 'Document  failed.' = 2 
BizWalk 'Record unavailable.' = 1 
Voltuas 'Order  already shipped.' = 1 
Gonda   'Document  failed.' = 1 

请注意

Voltuas 'Record unavailable.' = 1 
Voltuas 'Record unavailable' = 1

没有分组,因为一个有句号而另一个没有。您也可以替换它,或者更可能在您的真实数据中替换它,所有这些都以句点结尾。

【讨论】:

以上是关于SQL Server 或 C# - 将相似的记录归为一组的主要内容,如果未能解决你的问题,请参考以下文章

mongoDB聚合将相似的文档彼此相邻分组

有效地将相似的数字组合在一起[重复]

Excel 公式将相似的值替换为单个公式

Python3 - 将相似的字符串分组在一起

将相似的文件名移动到目录 - Bash

从许多数字和字符图片中进行图像聚类,将相似的图片组合在一起