回答

收藏

Transact SQL中Jaro Winkler距离算法的实现

技术问答 技术问答 177 人阅读 | 0 人回复 | 2023-09-14

我一直想知道如何在Transact
- J) }( A9 ^  \4 a8 E# YSQL中实现此算法,https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance
5 \  ^, ?3 E/ r$ |9 ^怎么做到呢?
' u, q+ E1 ?( ?& ?- ?- x' C) d9 y( O               
9 E( S. ~% q0 L解决方案:; T5 H: l4 \" D
                3 r5 O) Y, V' w" a% `
8 `: [; t" ~2 y; W

6 B$ |7 a, G6 y! Q0 Q% \& M                今天,我终于偶然发现了leebickmtu的这个Stack( r3 ~5 @) R- P
Overflow-answer,它显示了最初从Java移植的C#实现。我自由地将其移植到Transact SQL函数,请尽情享受!
( ]$ v; K/ r3 Y* b: `* L; n8 BIF OBJECT_ID (N'dbo.InlineMax', N'FN') IS NOT NULL
3 D3 I3 m2 X/ J3 D9 E) F' }+ K    DROP FUNCTION dbo.InlineMax;
' e2 E) c  D* T' t! ?$ UGO
8 Z4 X" y2 ?1 P! l% ]6 W( iCREATE FUNCTION dbo.InlineMax(@valueOne int, @valueTwo int)
) o8 Y9 S# }/ K' Y    RETURNS FLOAT
1 s. d! ~( y% y; i5 tAS
# u- M; U( R0 G! o+ T' F! b- iBEGIN
+ a; F3 j" Z- O4 w- _2 m    IF @valueOne > @valueTwo3 \0 _1 I4 R; ^0 S1 ?2 u. N) {
    BEGIN& K' X# C; Z* x
        RETURN @valueOne
- q7 X' R/ D2 S" [9 C3 M/ e    END) i6 u+ Z+ h1 `: V4 R
    RETURN ISNULL(@valueTwo, @valueOne)
8 A7 B! l5 [3 C! c" PEND;
" I' C9 Q, U0 ~/ U0 fGO& t# V0 Z; o  E0 H
IF OBJECT_ID (N'dbo.InlineMin', N'FN') IS NOT NULL5 ^: y4 V$ i5 e- I% {
    DROP FUNCTION dbo.InlineMin;
& e* l9 e, B( d( f* gGO8 r4 k& w4 c- Z" v
CREATE FUNCTION dbo.InlineMin(@valueOne int, @valueTwo int)
9 x; b* ?6 x' I3 D2 H; A: z$ i1 L    RETURNS FLOAT
% c6 t, o* @6 y9 HAS
2 i& N% n$ I1 F) Z7 w' B) j+ k/ _) {( mBEGIN- r: {" |- h2 p7 m/ c" ]& f
    IF @valueOne  (SELECT SUBSTRING(@stringTwo, @j, 1))6 j3 D0 j4 ]! T" i0 B
            BEGIN, m3 m" c) w  [- _  P
                SET @j = @j + 1( g7 g+ K2 B7 J6 H8 n! i
                CONTINUE3 L; g- T1 d8 t. e" x% m5 a! b
            END
" ^4 S: K# h3 e; m3 ~( T; `2 h            INSERT INTO @lMatched1 (position, [status]) VALUES(@i, 1)
/ Y; A# x  E# Y# {& {( _            INSERT INTO @lMatched2 (position, [status]) VALUES(@j, 1)  v3 I6 b" t% t7 E7 j
            SET @lNumCommon = @lNumCommon + 1' T: e- q) I; y; w2 U
            BREAK
. R; K) z/ U& \7 I        END
' f% U: R: C4 R' q2 O' B% t. W# D0 z        SET @i = @i + 1$ ~7 P  ]/ i+ }5 B5 g- I
    END
0 S3 F( T! P% @: v3 y0 V    IF @lNumCommon = 03 }# g1 H, d) c) ?: o! S6 k  V4 C
    BEGIN
, v0 c& }1 N0 ]1 z7 w/ s8 _        RETURN 0.0;- G4 l% |2 T. h  h0 @5 v$ b
    END
8 c1 y/ D# B: v' ]    DECLARE @lNumHalfTransposed int; SET @lNumHalfTransposed = 0
( p+ d7 S4 S: _3 r: R- `    DECLARE @k INT; SET @k = 1;$ {# F$ i1 N' q# A$ i
    DECLARE @stopLoop bit; SET @stopLoop = 0;1 W- f/ F2 z, d# V6 G
    SET @i = 1; WHILE(@i  (SELECT SUBSTRING(@stringTwo, @k, 1)))
) e% M+ A  F) v& A  f& S+ `+ n  a                SET @lNumHalfTransposed = @lNumHalfTransposed + 1
$ ^+ b- Q' M+ }3 r2 b- e            SET @k = @k + 1
1 T7 T1 B& ]" o% o2 l% }' d3 l        END
2 B* Y. s" c  D2 @: x; [        SET @i = @i + 1. W) K4 x6 p) j5 `
    END0 p4 A; k+ C/ j, i
    DECLARE @lNumTransposed INT; SET @lNumTransposed = @lNumHalfTransposed/2;: X/ |2 {4 P4 Z8 ~
    DECLARE @lNumCommonD FLOAT; SET @lNumCommonD = @lNumCommon; e7 n% C/ G  a0 _+ ]; e
    DECLARE @lWeight FLOAT; SET @lWeight = (@lNumCommonD / @lLen1 + @lNumCommonD / @lLen2 + (@lNumCommon - @lNumTransposed) / @lNumCommonD) / 3.0;; ~7 x5 c7 i/ _; x- W) f5 V
    IF(@lWeight <= @mWeightThreshold)
$ Y6 m! e; W  @, W# z3 ^        RETURN @lWeight. J% }$ E8 U$ w" e+ y: D: P
    DECLARE @lMax INT; SET @lMax = dbo.InlineMin(@mNumChars, dbo.InlineMin(@lLen1, @lLen2))' J: q4 x6 i; j! ^
    DECLARE @lPos INT; SET @lPos = 06 g: \$ l+ R* J% }* Q
    WHILE(@lPos < @lMax AND (SELECT SUBSTRING(@stringOne, @lPos, 1)) = (SELECT SUBSTRING(@stringTwo, @lPos, 1)))
7 L2 _" o; c7 N' R2 V, \% G    BEGIN6 y3 f$ X# d2 b4 s$ n/ j/ ?% c# i
        SET @lPos = @lPos + 1
3 Y' e) C! ~( s6 E& v    END
; o) Q& `( T" p; ^9 X    IF @lPos = 0  ]; p; Z( N# Z7 I2 o
        RETURN @lWeight
" k' ~: _8 N: a    RETURN @lWeight + 0.1 * @lPos * (1.0 - @lWeight)% F0 C+ m# \5 ^! [+ B! r
END;& s* m1 E0 E3 e. ]" V* x1 p+ b
GO
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则