查询具有相似值的SQL

时间:2019-06-21 17:22:27

标签: sql sql-server tsql

我必须使用类似12345678的字符串作为比较查询基数,但是要比较的值是这种方式12.345.678,如果我执行以下查询,它不会返回任何东西。

SELECT * FROM TABLA WHERE CAMPO = '12345678'

如果CAMPO的值为(12.345.678),如果我将=替换为like,则它也不会返回数据

SELECT * FROM TABLA WHERE CAMPO like '12345678%'
SELECT * FROM TABLA WHERE CAMPO like '%12345678'
SELECT * FROM TABLA WHERE CAMPO like '%12345678%'

以前的3次咨询都不适合我,如何查询?

该值可以是7、8或9个数字和。从头到尾必须是每3个

5 个答案:

答案 0 :(得分:3)

您可以将不带点的字符串与REPLACE(StringWithDots, '.','')

进行比较

答案 1 :(得分:3)

使用 REPLACE() 函数将所有'.'点替换为

SELECT *
FROM(
     VALUES ('12.345.678'),
            ('23.456.789')
    ) T(CAMPO)
WHERE REPLACE(CAMPO, '.', '') = '12345678';

您的查询应该是

SELECT * FROM TABLA WHERE REPLACE(CAMPO, '.', '') = '12345678';

答案 2 :(得分:0)

我建议您将数字转换为数字

因此,您可以使用<和>运算符以及所有需要输入数字的功能...

实现此目的的最佳方法是确保删除所有不必要的点并将逗号转换为点。像这样

CONVERT(NUMERIC(10, 2), 
               REPLACE(
                       REPLACE('7.000,45', '.', ''),
                       ',', '.'
                      )
              )

我希望这会对您有所帮助。

答案 3 :(得分:0)

一种SARGABLE解决方案是编写一个函数,该函数将您的目标值('12345678')从右到左每隔三个字符插入一个分隔符('.')。然后可以将结果('12.345.678'用于where子句中,并从CAMPO上的索引中受益。

以下代码演示了一种无需创建用户定义函数(UDF)的方法。取而代之的是,使用递归公用表表达式(CTE)一次处理输入字符串三个字符,以构建点分目标字符串。结果用于查询样本表。

要查看递归CTE的结果,请将最后的select语句替换为紧接其上方的注释select

-- Sample data.
declare @Samples as Table ( SampleId Int Identity, DottedDigits VarChar(20) );
insert into @Samples ( DottedDigits ) values
  ( '1' ), ( '12' ), ( '123' ), ( '1.234' ), ( '12.345' ),
  ( '123.456' ), ( '1.234.567' ), ( '12.345.678' ), ( '123.456.789' );
select * from @Samples;

-- Query the data.
declare @Target as VarChar(15) = '12345678';

with
  Target as (
    -- Get the first group of up to three characters from the tail of the string ...
    select
      Cast( Right( @Target, 3 ) as VarChar(20) ) as TargetString,
      Cast( Left( @Target, case when Len( @Target ) > 3 then Len( @Target ) - 3 else 0 end ) as VarChar(20) ) as Remainder
    union all
    -- ... and concatenate the next group with a dot in between.
    select
      Cast( Right( Remainder, 3 ) + '.' + TargetString as VarChar(20) ),
      Cast( Left( Remainder, case when Len( Remainder ) > 3 then Len( Remainder ) - 3 else 0 end ) as VarChar(20) )
      from Target
      where Remainder != ''
  )
  -- To see the intermediate results replace the final   select   with the line commented out below:
  --select TargetString from Target;
  select SampleId, DottedDigits
    from @Samples
    where DottedDigits = ( select TargetString from Target where Remainder = '' );

另一种方法是将indexed computed column添加到包含Replace( CAMPO, '.', '' )的表中。

答案 4 :(得分:0)

如果包含诸如12.345.678之类的ID的表很大(包含许多记录),我将添加一个计算字段以删除点(并且该ID绝不包含点以外的任何字母数字字符,并且不包含任何有效数字)前导零然后将其强制转换为INT或BIGINT),并将其保留并在其上放置索引。这样,您在插入记录时会花一点时间,但是以最大的速度查询它,从而节省了处理器的功耗。