sql查询返回与搜索键匹配的结果,但也检索搜索键后按字母顺序排列的记录

时间:2015-11-18 17:04:03

标签: sql sql-server sql-server-2008 substring patindex

标题是满口的,但我发现很难解释。

我有一个以前的网络服务,允许用户输入搜索键,例如4,这将返回以该搜索键开头的记录 例如4,4a,4b。

现在我被要求实施一个解决方案,如果用户输入4,它将返回结果:

Invoke-Command -ScriptBlock $doSomething -Session $session  

50条记录。

我不确定从哪里开始更改查询...被搜索的col是字母数字,这是令人困惑的位。

查询本身超过20行,但将结果链接到搜索键的部分只是;

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

根据要求,订购是:

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

现在如果我以82传递,我得到的结果是:

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,8x,9,9x等结果。

2 个答案:

答案 0 :(得分:1)

如果您想在搜索键后按字母顺序排列,请使用>=

where col >= @searchKey

答案 1 :(得分:1)

您需要从alpha部分中分离出数字部分,然后将它们重新组合成一个可以进行排序和过滤的新数字值。您需要对用户输入执行相同的操作。

请注意,这并不能处理您在帖子中提到的时间段,因为您没有告诉我们应该如何处理它。如果它不相关,那么使用replace函数来摆脱它。此外,这不处理字符串的alpha部分长于一个字符的情况。

我假设用户可以在数字输入后输入字符。如果不是这种情况,可以通过不必转换用户输入而不必将数字部分乘以大数来简化这一点。

100000应该大于字符串数字部分中可能的最大数量。根据需要为其添加额外的零。

SQL Fiddle

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