我正在尝试在JOIN ON
子句中构建case / if语句。
LEFT JOIN [CTSTRC] [Statuses] ON RIGHT([Statuses].[STRID], 3) = [CTE].[F61]
问题是列[Statuses].[STRID]
包含文本和数字。我将它与[CTE].[F61]
进行比较的列是一个整数。
有没有办法检测列[Statuses].[STRID]
是否有字符或数字?如果它是字符,那么将它设置为0?
这是一个帮助的伪查询:
LEFT JOIN [CTSTRC] [Statuses] ON RIGHT((CASE [Statuses].[STRID] WHEN TEXT THEN 0 ELSE CAST([Statuses].[STRID] AS INT) END), 3) = [CTE].[F61]
有人能指出我正确的方向吗?
谢谢!
答案 0 :(得分:16)
您正在寻找IsNumeric,但它并不总是有用(+, - 和。是数字),因此您需要使用解决方案described by GBN将.0e0添加到您的varchar
LEFT JOIN [CTSTRC] [Statuses] ON
(CASE WHEN ISNUMERIC(RIGHT([Statuses].[STRID], 3) + '.0e0) = 1
THEN CAST(RIGHT([Statuses].[STRID], 3) AS INT)
ELSE 0 END) = [CTE].[F61]
答案 1 :(得分:4)
创建一个持久的计算列并在其上添加索引。
ALTER TABLE YourTable ADD
NewIntID AS (CASE ISNUMERIC(RIGHT([Statuses].[STRID], 3) + '.0e0)
WHEN 1 THEN CAST(RIGHT([Statuses].[STRID], 3) AS INT)
ELSE 0
END) PERSISTED
GO
CREATE INDEX IX_YourTable_NewIntID
ON YourTable (NewIntID );
GO
您现在可以加入新的NewIntID列,就好像它现在是正确的数字ID一样。
答案 2 :(得分:3)
您可以尝试在Statuses表中创建一个表达式列,将右侧3个字符转换为数字,然后尝试连接表达式列。
答案 3 :(得分:1)
不会像这样的工作:
LEFT JOIN [CTSTRC] [Statuses] ON RIGHT([Statuses].[STRID], 3) = cast([CTE].[F61] as varchar(3))
您真正关心的是您是否匹配,那么为什么不将数字转换为varchar?你必须测试这两个想法,看看哪一个更快。
我同意@KM,修复这样糟糕的设计是最好的解决方案。在连接中使用函数和Case语句表明您的设计存在致命缺陷且应该修复。
答案 4 :(得分:0)
您正在寻找ISNUMERIC函数(我相信它是在SQL 2005中引入的):
LEFT JOIN [CTSTRC] [Statuses] ON
(CASE ISNUMERIC(RIGHT([Statuses].[STRID], 3)) WHEN 0 THEN 0 ELSE CAST(RIGHT([Statuses].[STRID], 3) AS INT) END) = [CTE].[F61]
答案 5 :(得分:0)
你可能想尝试这样的事情
select ...
from CTE
inner join
(
select ...
from [Statuses]
where ISNUMERIC(STRID + '.0e0') = 1
) rsNumeric on CTE.F61 = rsNumeric.STRID