您可以使用CASE 表达式:
SELECT *
FROM dbo.IpPbxCDR
WHERE CASE WHEN dbo.IpPbxCDR.OriginationNumber LIKE '+31%'
THEN '0' + Right(dbo.IpPbxCDR.OriginationNumber,9)
ELSE Replace(dbo.IpPbxCDR.OriginationNumber,'+','00'))
END = '0201234567';
注意我已经替换[dbo.IpPbxCDR]
为就像dbo.IpPbxCDR
这将寻找一个名为dbo.IpPbxCDR
而不是IpPbxCDR
在dbo
模式中调用的表的表。
附录
我不知道它是否适用,但上面不会使用您可能拥有的任何索引OriginationNumber
,如果您在 select 中使用表达式,这很好,但在 where 子句中可能会导致性能问题. 要使用索引,您可以重写如下:
DECLARE @Number VARCHAR(10) = '0201234567';
SELECT *
FROM dbo.IpPbxCDR
WHERE OriginationNumber = CASE WHEN @Number LIKE '00%' THEN STUFF(@Number, 1, 2, '+') ELSE STUFF(@Number, 1, 1, '+31') END;
这会对常量进行所有操作,因此只进行一次,而不是对每一行执行函数。为了进行比较,这是运行 ablve(顶部)与第一个查询(底部)相比时的执行计划:
测试模式
CREATE TABLE dbo.IpPbxCDR (OriginationNumber VARCHAR(15));
INSERT dbo.IpPbxCDR (OriginationNumber)
VALUES ('+31201234567'), ('+3469694535'), ('+44208979754');
INSERT dbo.IpPbxCDR (OriginationNumber)
SELECT TOP 10000 '+312012' + RIGHT('0000' + CAST(ROW_NUMBER() OVER(ORDER BY a.Object_ID) AS VARCHAR(5)), 5)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
UNION ALL
SELECT TOP 10000 '+342012' + RIGHT('0000' + CAST(ROW_NUMBER() OVER(ORDER BY a.Object_ID) AS VARCHAR(5)), 5)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
UNION ALL
SELECT TOP 10000 '+332012' + RIGHT('0000' + CAST(ROW_NUMBER() OVER(ORDER BY a.Object_ID) AS VARCHAR(5)), 5)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
CREATE NONCLUSTERED INDEX IX_IpPbxCDR_OriginationNumber ON dbo.IpPbxCDR (OriginationNumber);