SQL Server替换和检查是否存在

时间:2014-11-01 10:09:53

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

我必须在WHERE条件中使用以下方案检查字符串。

存储在数据库中的数据ProductId可以像

7314-3337有时使用 - 符号而不带前缀19

73143337有时没有符号而且没有前缀19

1973143337格式正确

197314-3337有时带 - 符号

我需要过滤记录ProductId,输入格式正确,即1973143337

WHERE P.ProductId=@ProductId 

如果数据以其他3种格式存储,我如何过滤?

如果SQL服务器中不存在字符串replace( - )和前缀19,该如何使用?

3 个答案:

答案 0 :(得分:3)

请检查这2方法。  一个很简单,第二个是一些技巧。 (我认为你选择了涵盖所有事情的第二种选择)

declare @t table (ProductId varchar(100))

insert into @t
values
('7314-3337')
,('73143337')
,('1973143337')
,('197314-3337')
,('73683337')
,('73143338')

declare @valuetosearch varchar(100) = '1973143337'
--this is very simple , but not work in each schenerio. the second approach is fine.
--select CHARINDEX ( '19','1973143337'), SUBSTRING('1973143337',3,len('1973143337'))

--select * from 
--@t 
--where 
--replace(REPLACE(ProductId ,'-','') ,'19','') = replace(REPLACE(@valuetosearch ,'-','') ,'19','')

select * from 
@t 
where 
REPLACE( case when CHARINDEX ( '19',ProductId) = 1
then SUBSTRING( ProductId ,3,LEN(ProductId))
else ProductId
end ,'-','')
=
REPLACE ( case when CHARINDEX ( '19',@valuetosearch) = 1
then SUBSTRING( @valuetosearch ,3,LEN(@valuetosearch))
else @valuetosearch
end ,'-','')

答案 1 :(得分:1)

您应首先清理您的数据,如果数据不一致,那么您将无法获得正确的结果。

用于前缀19:

UPDATE foo
SET ProductId = '19' + ProductId
WHERE Left(ProductID, 2) <> '19'

删除&#39; - &#39;:

UPDATE foo
SET ProductId = REPLACE(ProductId, '-', '')

然后你应该能够得到你想要的结果。

更新:

您可以使用单一格式构建CTE,然后筛选CTE:

WITH cte (
FormattedPID
,ProductId
)
AS (
SELECT CASE 
        WHEN LEFT(ProductId, 2) = '19'
            THEN REPLACE(ProductId, '-', '')
        ELSE '19' + REPLACE(ProductId, '-', '')
        END
    ,ProductId
FROM foo
)
SELECT FormattedPID
     ,ProductId
FROM cte
WHERE FormattedPID = @ProductID

答案 2 :(得分:0)

您可以确保列的格式正确如下:

  1. 删除-,将其替换为空字符串(197314-3337 -> 1973143337, 7314-3337 -> 73143337)。

  2. 在开头添加191973143337 -> 191973143337, 73143337 -> 1973143337)。

  3. 取结果中最右边的10个字符并与输入(1973143337 -> 1973143337, 1973143337 -> 1973143337)进行比较。

  4. 在Transact-SQL中:

    WHERE RIGHT('19' + REPLACE(P.ProductId, '-', ''), 10) = @ProductId
    

    当然,这意味着没有索引寻找你,因为我们正在向列中应用函数。

    另一种方法是从输入中产生三种非标准格式:

    • 切断了最初的191973143337 -> 73143337);

    • 插入-1973143337 -> 197314-3337);

    • 插入-并切断191973143337 -> 197314-3337 -> 7314-3337)。

    在Transact-SQL中:

    WHERE P.ProductId IN (
      @ProductId,
      SUBSTRING(@ProductId, 3, 999999999),
      STUFF(@ProductId, 7, 0, '-'),
      SUBSTRING(STUFF(@ProductId, 7, 0, '-'), 3, 999999999)
    )
    

    这样,如果P.ProductId上有索引,它将被有效使用。

    两种方法都假定正确格式的长度是固定的。