SQL按百分比匹配字符串

SQL按百分比匹配字符串,sql,database,entity-framework,linq,linq-to-entities,Sql,Database,Entity Framework,Linq,Linq To Entities,我有一个SQL表,有两列-ID,Value 比如说 ID VALUE 1 008_ADL_S81_PCIE_L2_B2B_Cycling_Failure_Phystatus_PP 2 008_ADL_S81_ABC 3 008_ADL_DEF 4 008_ADL_XYZ 我需要构建一个查询,搜索我的字符串是否在我的表中的值列中找到,或者如果我用“下划线”将字符串拆分为单词,它至少匹配70% 例如,下面的字符串与我的表ID=1匹配,因为90%的“单词”(用“下划线

我有一个SQL表,有两列-ID,Value 比如说

ID   VALUE
1    008_ADL_S81_PCIE_L2_B2B_Cycling_Failure_Phystatus_PP 
2    008_ADL_S81_ABC
3    008_ADL_DEF 
4    008_ADL_XYZ
我需要构建一个查询,搜索我的字符串是否在我的表中的值列中找到,或者如果我用“下划线”将字符串拆分为单词,它至少匹配70% 例如,下面的字符串与我的表ID=1匹配,因为90%的“单词”(用“下划线”拆分后)是相同的,高于70%

008_ADL_A0_S81_PCIE_L2_B2B_Cycling_Failure_Phystatus_PP 

如何操作?

假设您的表足够小,可以在客户端本地加载它,并且假设您正在使用LINQ to数据库并需要LINQ查询,则可以使用:

var target = "008_ADL_A0_S81_PCIE_L2_B2B_Cycling_Failure_Phystatus_PP";
var targetHS = target.Split('_', StringSplitOptions.RemoveEmptyEntries).ToHashSet();

var matchingIDs = db.AsEnumerable()
                    .Select(s => new { s.ID, words = s.VALUE.Split('_', StringSplitOptions.RemoveEmptyEntries) })
                    .Where(s => s.words.Count(w => targetHS.Contains(w)) / s.words.Length >= 0.70)
                    .Select(s => s.ID)
                    .ToList();
或者,如果表很大,可以将表筛选为至少包含一个匹配项的行,然后在客户机上处理百分比

使用基于的一些扩展方法来构建查询谓词:

public static class LinqKitExt {
    // string fieldExpr(T row) - function returning multiple value string field to test
    // delimiter - string separator between values in test field
    // value - string value to find in values of test field
    // r => fieldExpr(r).Split(delimiter).Contains(value)
    public static Expression<Func<T, bool>> SplitContains<T>(this Expression<Func<T, string>> fieldExpr, string delimiter, string value) {
        var pred = PredicateBuilder.New<T>(r => fieldExpr.Invoke(r) == value);
        pred = pred.Or(r => fieldExpr.Invoke(r).StartsWith(value + delimiter));
        pred = pred.Or(r => fieldExpr.Invoke(r).EndsWith(delimiter + value));
        pred = pred.Or(r => fieldExpr.Invoke(r).Contains(delimiter + value + delimiter));

        return pred;
    }

    // values - string values, one of which to find in values of test field
    // string fieldExpr(T row) - function returning multiple value string field to test
    // delimiter - string separator between values in test field
    // r => values.Any(value => fieldExpr(r).Split(delimiter).Contains(value))
    public static Expression<Func<T, bool>> AnySplitContains<T>(this IEnumerable<string> values, Expression<Func<T, string>> fieldExpr, string delimiter) {
        var pred = PredicateBuilder.New<T>();
        foreach (var value in values)
            pred = pred.Or(fieldExpr.SplitContains(delimiter, value));

        return pred;
    }

    // values - string values, one of which to find in values of test field
    // string fieldExpr(T row) - function returning multiple value string field to test
    // delimiter - string separator between values in test field
    // dbq.Where(r => values.Any(value => fieldExpr(r).Split(delimiter).Contains(value)))
    public static IQueryable<T> WhereAnySplitContains<T>(this IQueryable<T> dbq, IEnumerable<string> values, Expression<Func<T, string>> fieldExpr, string delimiter) =>
        dbq.AsExpandable().Where(values.AnySplitContains(fieldExpr, delimiter));
}

(1) 定义“70%”匹配的含义。(2) 提供一个数据库标签。(3) SQL通常不是进行此类处理的最佳工具。1。70%匹配意味着如果我将要搜索的字符串按“下划线”拆分为单词,并将表值列按“下划线”拆分为单词,70%的字符串是相同的DB is SQL…我还有什么其他选项?SQL只是一种语言。您的数据库可以是SQL Server、Oracle、MySQL等等。每个数据库都有一个稍微不同的结构化查询语言(SQL)实现。@MichaelGroiser SQL只是一种语言而不是数据库,您使用的数据库引擎是什么?我猜,既然你在.Net世界,那就是Microsoft SQL server
var matchingIDs = db.WhereAnySplitContains(targetHS, r => r.VALUE, "_")
                    .AsEnumerable()
                    .Select(s => new { s.ID, words = s.VALUE.Split('_', StringSplitOptions.RemoveEmptyEntries) })
                    .Where(s => s.words.Count(w => targetHS.Contains(w)) / s.words.Length >= 0.70)
                    .Select(s => s.ID)
                    .ToList();