Sql server 获得两个字符串之间的最高一致性

Sql server 获得两个字符串之间的最高一致性,sql-server,sql-server-2008,tsql,sql-server-2014,string-comparison,Sql Server,Sql Server 2008,Tsql,Sql Server 2014,String Comparison,Levenshtein函数是找到两个字符串之间最高一致性的正确/最佳函数吗 例如: 我的最终结果应该是CCC14E0APJ是CCC14E0APJ123的主产品。 我无法精确匹配,因为有些产品看起来会像这样 CCC14E0AP CCC14E0APJ CCC14E0APK 都是完全不同的产品。 对于找到的最长字符串,主字符串始终是100%匹配字符串。 对于产品abcde123,如果主表中有abcde,则为主表。如果只有abc,那就是主字符串。您不需要想象字符串函数有多接近,而是将字符串的开头与所有

Levenshtein函数是找到两个字符串之间最高一致性的正确/最佳函数吗

例如:

我的最终结果应该是
CCC14E0APJ
CCC14E0APJ123
的主产品。 我无法精确匹配,因为有些产品看起来会像这样

CCC14E0AP
CCC14E0APJ
CCC14E0APK
都是完全不同的产品。 对于找到的最长字符串,主字符串始终是100%匹配字符串。 对于产品abcde123,如果主表中有abcde,则为主表。如果只有abc,那就是主字符串。

您不需要想象字符串函数有多接近,而是将字符串的开头与所有其他字符串(如果它们以相同的字符串开头)进行比较。如果是这样的话,越短的就是越长的父项

通过以下查询,您将获得ParentID,即使在分层系统中也是如此:

DECLARE @dummy TABLE(YourID VARCHAR(100),ParentID VARCHAR(100));

INSERT INTO @dummy(YourID) VALUES
 ('CCC14E0AP')
,('CCC14E0APJ')
,('CCC14E0APK')
,('CCC14E0APK_1')
,('CCC14E');

WITH DependingIDs AS
(
    SELECT d.ParentID
          ,d.YourID
          ,d2.YourID AS dependingID
          ,RANK() OVER(PARTITION BY d.YourID ORDER BY LEN(d2.YourID) DESC) AS NextLenght
    FROM @dummy AS d
    INNER JOIN @dummy AS d2 ON d.YourID LIKE d2.YourID + '%' AND d.YourID<>d2.YourID
)
UPDATE DependingIDs SET ParentID=dependingID
WHERE NextLenght=1;

SELECT * FROM @dummy
您不需要想象字符串函数有多接近,而是将字符串的开头与所有其他字符串(如果它们以相同的字符串开头)进行比较。如果是这样的话,越短的就是越长的父项

通过以下查询,您将获得ParentID,即使在分层系统中也是如此:

DECLARE @dummy TABLE(YourID VARCHAR(100),ParentID VARCHAR(100));

INSERT INTO @dummy(YourID) VALUES
 ('CCC14E0AP')
,('CCC14E0APJ')
,('CCC14E0APK')
,('CCC14E0APK_1')
,('CCC14E');

WITH DependingIDs AS
(
    SELECT d.ParentID
          ,d.YourID
          ,d2.YourID AS dependingID
          ,RANK() OVER(PARTITION BY d.YourID ORDER BY LEN(d2.YourID) DESC) AS NextLenght
    FROM @dummy AS d
    INNER JOIN @dummy AS d2 ON d.YourID LIKE d2.YourID + '%' AND d.YourID<>d2.YourID
)
UPDATE DependingIDs SET ParentID=dependingID
WHERE NextLenght=1;

SELECT * FROM @dummy

对于每一行,您只需使用
APPLY
运算符检测最大子字符串:

DECLARE @t TABLE ( p VARCHAR(MAX) );

INSERT  INTO @t
VALUES  ( 'A' ),
        ( 'AAAA' ),
        ( 'AA' ),
        ( 'BBB' ),
        ( 'BBBB' ),
        ( 'BBBBB' ),
        ( 'BBBBB' ),
        ( 'C' )

SELECT  *
FROM    @t t
        OUTER APPLY ( SELECT TOP 1 p
                      FROM      @t
                      WHERE     t.p <> p AND t.p LIKE p + '%'
                      ORDER BY  LEN(p) DESC
                    ) ca

对于每一行,您只需使用
APPLY
运算符检测最大子字符串:

DECLARE @t TABLE ( p VARCHAR(MAX) );

INSERT  INTO @t
VALUES  ( 'A' ),
        ( 'AAAA' ),
        ( 'AA' ),
        ( 'BBB' ),
        ( 'BBBB' ),
        ( 'BBBBB' ),
        ( 'BBBBB' ),
        ( 'C' )

SELECT  *
FROM    @t t
        OUTER APPLY ( SELECT TOP 1 p
                      FROM      @t
                      WHERE     t.p <> p AND t.p LIKE p + '%'
                      ORDER BY  LEN(p) DESC
                    ) ca

字符串的前缀是否总是一致,或者可能也会有所不同?始终一致,所有字符及其顺序都应该完全匹配为什么CCC14E0APJ123高于CCC14E0AP、CCC14E0APK?事实并非如此。CCC14E0APJ=主产品,CCC14E0APJxxxxx=CCC14E0APJ和CCC14E0APK的子产品X和CCC14E0APMASTER?字符串的前缀是否始终一致,或者可能也会有所不同?始终一致,所有字符及其顺序都应该完全匹配为什么CCC14E0APJ123高于CCC14E0AP,CCC14E0APK?事实并非如此。CCC14E0APJ=主产品,CCC14E0APJxxxxx=子产品X和CCC14E0APJ&CCC14E0APK的CCC14E0AP主产品?您的解决方案也很有效,但Shnugo的解决方案是第一个,也很有效,我无法说出这两种解决方案的优缺点。@在这种情况下,您可以通过点击三角形来投票决定答案。投票和接受是两个独立的步骤。因为你自己已经越过了15个代表点的边界,你被要求对任何你喜欢或不喜欢的贡献进行投票。这是对你说谢谢的方式,所以。。。快乐编码!(顺便说一句:+1从我这边)你的解决方案也很有效,但Shnugo的解决方案是第一个,也很有效,我无法说出这两种解决方案的优缺点。@jrdev22在这种情况下,你可以通过点击三角形来投票。投票和接受是两个独立的步骤。因为你自己已经越过了15个代表点的边界,你被要求对任何你喜欢或不喜欢的贡献进行投票。这是对你说谢谢的方式,所以。。。快乐编码!(顺便说一句,我这边+1)
A       NULL
AAAA    AA
AA      A
BBB     NULL
BBBB    BBB
BBBBB   BBBB
BBBBB   BBBB
C       NULL