-2

列 firstname を持つテーブルがあります。たとえば、ABC を入力しました。ここでの問題は、firstname = ABC だけでなく、CAB、CBA、または BAC も検索したいのです。

これを行う方法はありますか。

ありがとう

4

2 に答える 2

1

最初に、文字列(たとえば、「ABC」)を取得し、指定された文字列のすべての順列(たとえば、「ABC」、「ACB」、「BAC」、「BCA」、「CAB」、「CBA」)を含むテーブルを返す関数を作成します。

私はここからJavaの実装に基づいてそのような関数を作成しました:

CREATE FUNCTION [dbo].[permuteString] (@beginStr varchar(10),@endStr varchar(10))
RETURNS @result table (result varchar(10)) 
AS
BEGIN
     declare @i int
     declare @curStr varchar(10)
     if LEN(@endStr) <= 1
           insert into @result select @beginStr+@endStr
     else
           begin
                set @i = 1
                while(@i <= LEN(@endStr))
                begin
                  set @curStr = case when @i > 1 then substring(@endStr,1, @i-1) else '' end
                                + substring(@endStr, @i + 1, LEN(@endStr)-@i)        
                  insert into @result 
                  select * from dbo.permuteString(@beginStr + substring(@endStr,@i,1), @curStr)
                  set @i = @i+1
                end
           end  
    return 
END

この関数がある場合は、クエリのステートメントと一緒に使用しinます。

select columnName
from tableName
where columnName in (select * from dbo.permuteString('',@inputString))

順列関数のその他の実装はここで確認できます: SQLサーバーで順列を生成する最も洗練された方法

于 2012-09-28T11:20:48.083 に答える
0

部分的な回答

解決するのが楽しい問題のようです。簡単な部分は、「ABC」を個々の文字に分割し、デカルト積を作成してそれらを独自の組み合わせに結合することです。難しいのは、デカルト積を処理する動的 SQL を作成することです。

を使用abcdして、例のデカルト積部分をより適切に説明します。

declare @val varchar(10) = 'abcd'

-- split the string apart
declare @len int = datalength(@val), @i int = 1

select cast(null as int) as id, cast(null as char(1)) as c
into   #temp
where  1=2

while @i <= @len
begin
  insert into #temp
  values (@i, substring(@val, @i, 1))

  set @i = @i + 1
end

-- pull the combinations (need to make this into dynamic SQL)
select a.c + b.c + c.c + d.c as names
into   #combos
from   #temp a, #temp b, #temp c, #temp d
where  a.id <> b.id and a.id <> c.id and a.id <> d.id and
                        b.id <> c.id and b.id <> d.id and
                                         c.id <> d.id

-- check work
select * from #combos

-- use the combos to pull records where the first name matches...
-- select * from [table] where firstname in (select names from #combos)

drop table #temp, #combos

申し訳ありませんが、動的 SQL を理解する時間がありません。それを正しく取得するのは難しいでしょう。文字を追加するたびに、指数関数的なバルクが dyn-SQL に追加されます。

これは、「Suzanne」という名前のように重複する文字を排除しません。

于 2012-09-28T06:08:23.403 に答える