1

T-SQLでは、文字列に2つ以上の類似した文字が含まれているかどうかをどのように確認しますか?

「5512111445」、「6612888445」、または「5512zzz44x」などの非表示の番号である可能性があるnvarcharの携帯電話番号が列に含まれています

「xx12yyy4zx」の検索パターンをユーザーが入力しました。一致したすべての番号をこのパターンに戻したいのですが、x、y、zは任意の番号を表しますが、繰り返すと同じ番号を表します。たとえば、前のパターンでは、上記のすべての数値が返されます。

xxは55や66のような類似した数字ですが、xyは45や67のような異なる数字です。

これはどのように行うことができますか?

4

2 に答える 2

2

面倒なので、すべてをコーディングするつもりはありませんが、これで始めることができると思います。

  1. 検索パターンを同様のパターンに変換し、すべてのアルファベット文字をアンダースコアに置き換えます。これにより、検索する必要のある行の数が減りますが、それでもふるいにかけることがたくさんあります。
  2. パターン内の文字ごとに、パターンに一致する行をフィルタリングします。「5512zzz44x」の例:
    1. 'z'で開始:
      • 「5512zzz44x」->「5512zzz44_」
      • パスごとに行を除外する結果をループするか、動的SQLを生成して、すべてが作成された後に実行します。
      • "5512zzz44_"->... mobile_num like '551200044_' or mobile_num like '551211144_' ... or mobile_num_like '551299944_'
    2. 次の文字:'x':
      • "5512zzz44x"-> "5512 ___ 44x"
      • (上記2.1のパターンに従ってください)

アイデアは、元のパターンに一致する#のみが残るまで、結果を段階的に除外することです。

これを行うには、おそらくはるかに効率的な方法があります。CLRの展開がオプションである場合は、CLRと正規表現を使用してこれを実行することをお勧めします。

于 2012-04-17T01:09:06.727 に答える
2

マスクと数字の各文字を列にピボットしてから、マスクのみでグループ化し、その後にマスク+数字を続けることができます。この方法では、マスクのyが一意の数字にマップされないため、5512111445と6612888445はマスクxx12yyy4yzと一致しません。ただし、携帯電話番号5512111415および6612888485は、携帯電話番号5512zzz44xと同様に、マスクxx12yyy4yzと一致します。

--declare @mobileNums varchar(10)='5512111445'; --no match because @mask y maps to different values
--declare @mobileNums varchar(10)='6612888445'; --no match because @mask y maps to different values
--declare @mobileNums varchar(10)='5512111415'; --no match because @mask x should not equal @mask z
--declare @mobileNums varchar(10)='6612888485'; --matches
--declare @mobileNums varchar(10)='8812888485'; --no match because @mask x should not equal @mask y
--declare @mobileNums varchar(10)='5512zzz44x'; --matches because z and x are both hidden and different
--declare @mask varchar(10)='xx12yyy4yz';

declare @mobileNums varchar(10)='3211zyy'; -- no match because @mask y <> @mask z, but @mobileNums y = y
declare @mask varchar(10)='3211yxz';

declare @t table(n char, m char);
declare @i int=1;

while @i<=LEN(@mobileNums) begin
    insert into @t values (SUBSTRING(@mobileNums,@i,1), SUBSTRING(@mask,@i,1));
    set @i+=1;
end

if exists(
    -----------------------------------------------------------------------------
    -- Group by m
    select
    m, c=count(m)
    from @t
    where ISNUMERIC(n)=0 and ISNUMERIC(m)=0
    group by m
    except
    select
    m, c=count(m+n)
    from @t
    where ISNUMERIC(n)=0 and ISNUMERIC(m)=0
    group by m,n

    union

    select
    m, c=count(m)
    from @t
    where ISNUMERIC(n)=0 and ISNUMERIC(m)=1
    group by m
    except
    select
    m, c=count(m+n)
    from @t
    where ISNUMERIC(n)=0 and ISNUMERIC(m)=1
    group by m,n

    union

    select
    m, c=count(m)
    from @t
    where ISNUMERIC(n)=1 and ISNUMERIC(m)=0
    group by m
    except
    select
    m, c=count(m+n)
    from @t
    where ISNUMERIC(n)=1 and ISNUMERIC(m)=0
    group by m,n

    union

    select
    m, c=count(m)
    from @t
    where ISNUMERIC(n)=1 and ISNUMERIC(m)=1
    group by m
    except
    select
    m, c=count(m+n)
    from @t
    where ISNUMERIC(n)=1 and ISNUMERIC(m)=1
    group by m,n

    union

    -----------------------------------------------------------------------------
    -- Group by n

    -- Add a rule that no numeric @mobileNums digit can correspond to more than one alpha @mask character
    select
    n, c=count(m)
    from @t
    where ISNUMERIC(n)=1 and ISNUMERIC(m)=0
    group by n
    except
    select
    n, c=count(m+n)
    from @t
    where ISNUMERIC(n)=1 and ISNUMERIC(m)=0
    group by m,n 

    union

    -- For GROUP BY n, include the three remaining combinations of ISNUMERIC(n) and ISNUMERIC(m)
    select
    n, c=count(m)
    from @t
    where ISNUMERIC(n)=0 and ISNUMERIC(m)=0
    group by n
    except
    select
    n, c=count(m+n)
    from @t
    where ISNUMERIC(n)=0 and ISNUMERIC(m)=0
    group by m,n    

    union

    select
    n, c=count(m)
    from @t
    where ISNUMERIC(n)=0 and ISNUMERIC(m)=1
    group by n
    except
    select
    n, c=count(m+n)
    from @t
    where ISNUMERIC(n)=0 and ISNUMERIC(m)=1
    group by m,n 

)
select patMatch='False'
else 
select patMatch='True';

編集-数値の@mobileNums桁が複数のアルファ@マスク文字に対応できないというルールを追加します

編集-の場合GROUP BY n、ISNUMERIC(n)とISNUMERIC(m)の残りの3つの組み合わせを含めます

編集-8番目を削除しますUNION

于 2012-04-17T05:30:10.340 に答える