Data not filtering before a join
一个我无法弄清楚的同事的谜题......
1 2 3 4 5 6 7 8 9 10 11 | UPDATE btd.dbo.tblpayroll SET empname = ( SELECT b.Legal_Name FROM ( SELECT Legal_Name, Employee_ID FROM Com.dbo.Workers WHERE isnumeric(Employee_ID) = 1 ) b WHERE b.Employee_ID = empnum AND b.Legal_name IS NOT NULL ) WHERE empname IS NULL |
Msg 245, Level 16, State 1, Line 1
将 varchar 值"N0007"转换为数据类型 int 时转换失败。表别名 b 实际上是一个视图。
值"N0007"在 Workers 表中。我不明白为什么它没有从正在加入的结果中过滤掉。
编辑:
事实上,别名确实返回了正确的行 - 所以 isNumeric 正在完成这项工作。
我怀疑优化器试图在内部选择之前应用外部选择的 where 子句。据推测,它认为它能够对 Employee_ID 进行索引查找,从而在这种情况下实现更快的查询。尝试:
1 2 3 4 5 6 7 8 | UPDATE btd.dbo.tblpayroll SET empname = ( SELECT Legal_Name FROM Com.dbo.Workers WHERE isnumeric(Employee_ID) = 1 AND CONVERT(VARCHAR,Employee_ID) = CONVERT(VARCHAR,empnum) AND Legal_name IS NOT NULL) WHERE empname IS NULL |
将它们全部转换为 varchar 应该可以解决这个问题。我不认为它比您最初想要的效率低得多,因为如果首先完成 isnumeric,无论如何都会强制进行表扫描。
显而易见的事情是强制比较顺序,也许通过从只有数字 Employee_ID 的视图中获取名称,而不是完整的 Workers 表。
也许 N 被认为是货币符号?您可以尝试用
替换 IsNumeric
1 | LIKE REPLICATE('[0-9]',/*length of Employee_ID*/) |
或者只是
1 | LIKE '[0-9]%' |
如果字母不能在中间