【问题标题】:Select data between string range在字符串范围之间选择数据
【发布时间】:2019-07-09 07:38:23
【问题描述】:

我有一张桌子Employee

_________________________________
Id | name    |      salary                    
______________________________
1  | John    |   [1300 - 2000] 
_______________________________
2  | Aby     |   [600 - 1000] 
________________________________
3  | Mike    |   [1000 - 1500] 

工资栏是Nvarchar

我想要 SQL 中的 Query/Function/SP,如果我搜索 1400,输出应该如下所示

Id | name    |      salary                    
________________________________
1  | John    |   [1300 - 2000] 
_______________________________
3  | Mike    |   [1000 - 1500] 

提前致谢。

【问题讨论】:

  • Salary column is Nvarchar。那是一个错误。如果您有从/到范围,则需要为 FromTo 值使用两个单独的列,并使用 正确 类型 - 整数或小数,具体取决于值。一旦你修复了编写查询的错误
  • 没有理由将值范围存储为文本,该字符串不能被查询或索引。该字符串实际上比两个 bigint 或十进制列占用 更多 空间。即使该字符串来自遗留应用程序,也必须将其转换为两个单独的值以允许查询

标签: sql sql-server sql-server-2008 sql-server-2012


【解决方案1】:

您不应将范围存储在一列中。但是如果你不能改变它,那就是sollusion:

SELECT  [Id] , name, 
      ,[salary] 
  FROM [Test Database].[dbo].[test] where 
1700 >= RTRIM(LTRIM(SUBSTRING(salary,0, CHARINDEX('-',salary)))) 
and 1700 <=  RTRIM(LTRIM(SUBSTRING(salary, CHARINDEX('-', salary) + 1, LEN(salary))))

【讨论】:

  • 我在 SUBSTRING 之前使用 REPLACE 函数将 "[" & " ] " 替换为 "" 并且效果很好。谢谢....
  • SELECT [Id] , name, ,[salary] FROM [Test Database].[dbo].[test] where 1700 >= RTRIM(LTRIM(REPLACE(SUBSTRING(salary,0, CHARINDEX( '-',salary)),'[',''))) 和 1700
【解决方案2】:

你需要提取数值,然后转换为数值类型:

declare @mySalary money;
set  @mySalary = 1400;

with Employee(ID, Name, Salary ) as
(
 select 1,'John','[1300 - 2000]' union all
 select 2,'Aby','[600 - 1000]'   union all
 select 3,'Mike','[1000 - 1500]'
), e2 as
(
select SUBSTRING(Salary,PATINDEX('%[0-9]%', Salary),CHARINDEX('-',Salary)-2) as Salary1,
       SUBSTRING(Salary,CHARINDEX('-',Salary)+1,CHARINDEX(']',Salary)-CHARINDEX('-',Salary)-1) as Salary2,
       e.*
  from Employee e
)
select ID, Name, Salary
  from e2
 where @mySalary between cast(Salary1 as money) and cast(Salary2 as money);

ID  Name    Salary
1   John    [1300 - 2000]
3   Mike    [1000 - 1500]

Demo

【讨论】:

    【解决方案3】:

    试试这个查询:

    declare @tbl table (id int, name varchar(15), salary varchar(20));
    declare @mySalary int = 1400;
    
    insert into @tbl 
     select 1,'John','[1300 - 2000]' union all
     select 2,'Aby','[600 - 1000]'   union all
     select 3,'Mike','[1000 - 1500]'
    
    select id, name, salary from (
        select id, name, salary,
               convert(int, substring(salary, openBrcktIdx + 1, hyphenIdx - openBrcktIdx - 2)) lowerBound,
               convert(int, substring(salary, hyphenIdx + 2, closeBrcktIdx - hyphenIdx - 2)) upperBound
        from (
            select *,
                   charindex('-', salary) hyphenIdx,
                   charindex('[', salary) openBrcktIdx,
                   charindex(']', salary) closeBrcktIdx
            from @tbl
        ) t
    ) t where @mySalary between lowerBound and upperBound
    

    【讨论】:

      【解决方案4】:

      声明@var1 int =1400

      选择 * 来自 (select *,replace(SUBSTRING(salary,0,CHARINDEX('-',salary,0)),'[','') as Splitted1, 替换(SUBSTRING(salary,CHARINDEX('-',salary,0)+1,len(salary)-1),']','') as Splitted2 来自员工 ) 作为 t1 其中@var1>=Splitted1 和@var1

      https://rextester.com/l/sql_server_online_compiler

      【讨论】:

        猜你喜欢
        • 2013-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-24
        • 1970-01-01
        相关资源
        最近更新 更多