0

タイトルは一口ですが、説明するのが難しいと感じました。

ユーザーが 4 などの検索キーを入力できる以前の Web サービスがあり、その検索キー (4、4a、4b など) で始まるレコードが返されました。

ここで、ユーザーが 4 を入力すると結果が返されるソリューションを実装するように依頼されました。

4
4a
4aa
4b
5
5a
5b
5c
5Z
6
52.
etc.. 

50 レコードの場合。

クエリの変更をどこから始めればよいかわかりません...検索される列は英数字であり、それが紛らわしいビットです。

クエリ自体は 20 行を超えますが、結果と検索キーをリンクする部分はわずかです。

(col LIKE @searchKey + '[a-zA-Z.]%' OR col = @searchKey OR col >= @searchKey)

そして、要求された順序は次のとおりです。

ORDER BY   
        CASE WHEN col LIKE '[a-zA-Z]%' Then 1 ELSE 0 END,

                 CAST(SUBSTRING(col, 0, 

                  CASE WHEN patindex('%[a-zA-Z.]%', col) = 0

                  THEN len(col)+1

                  ELSE patindex('%[a-zA-Z.]%', col)

                  END) 

                 as INT),

    CASE WHEN col LIKE '[a-zA-Z]%' THEN SUBSTRING(col, 1,1) END,

    CASE WHEN col LIKE '[a-zA-Z]%' AND len(col) = 1 THEN 0 ELSE 1 END,

    CASE WHEN col LIKE '[a-zA-Z]%' AND len(col) = 2 THEN 0 ELSE 1 END,

    CASE WHEN col LIKE '[a-zA-Z]%' AND len(col) = 3 THEN 0 ELSE 1 END,

    col;

たとえば、現在 82 を渡すと、結果が得られます。

8
8A
8B
8E
8H
9
9A
9C
9D
9E
82
82A
82B
82C
.
.
.
.
99R

ただし、ユーザーが 82 と入力すると、8、8x、9、9x などの結果が返されないことが必要です。

4

2 に答える 2

1

数値部分をアルファ部分から分離し、それらを並べ替えてフィルター処理できる新しい数値に再結合する必要があります。ユーザー入力についても同じ操作を行う必要があります。

これは、投稿で言及した期間を処理しないことに注意してください。これは、処理方法を指定していないためです。不要な場合は、replace 関数を使用して削除します。また、これは、文字列のアルファ部分が 1 文字より長い状況を処理しません。

ユーザーが数値入力の後に文字を入力できると仮定しました。そうでない場合は、ユーザー入力を変換する必要がなく、数値部分に大きな数を掛ける必要がないため、単純化できます。

100000 は、文字列の数値部分で可能な最大数より大きくする必要があります。必要に応じてゼロを追加します。

SQL フィドル

declare @t table (col varchar(4))
declare @userinput varchar(4)

set @userinput = '9C'

insert into @t values ('8')
insert into @t values ('8A')
insert into @t values ('8B')
insert into @t values ('8E')
insert into @t values ('8H')
insert into @t values ('9')
insert into @t values ('9A')
insert into @t values ('9C')
insert into @t values ('9D')
insert into @t values ('9E')
insert into @t values ('82')
insert into @t values ('82A')
insert into @t values ('82B')
insert into @t values ('82C')
insert into @t values ('99R')

;with cte as (
    select 
        col,
        CONVERT(int,
            case when PATINDEX('%[a-z]%', col) = 0 
                then col
                else LEFT(col, PATINDEX('%[a-z]%', col) - 1)
            end
        ) * 100000
        +
        ascii(case when PATINDEX('%[a-z]%', col) = 0
            then ' '
            else SUBSTRING(col, PATINDEX('%[a-z]%', col), len(col))
        end) newcol

    from @t
)

select *
from cte
where 
    newcol >= (
        CONVERT(int,
            case when PATINDEX('%[a-z]%', @userinput) = 0 
                then @userinput
                else LEFT(@userinput, PATINDEX('%[a-z]%', @userinput) - 1)
            end
        ) * 100000
        +
        ascii(case when PATINDEX('%[a-z]%', @userinput) = 0
            then ' '
            else SUBSTRING(@userinput, PATINDEX('%[a-z]%', @userinput), len(@userinput))
        end)
    )
order by newcol
于 2015-11-25T22:17:46.067 に答える