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 yoyo
和lala 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# - 将相似的记录归为一组的主要内容,如果未能解决你的问题,请参考以下文章