【问题标题】:Data not filtering before a join加入前未过滤数据
【发布时间】:2008-12-03 22:54:42
【问题描述】:

来自同事的一个我无法弄清楚的谜题......

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

消息 245,第 16 级,状态 1,第 1 行 将 varchar 值“N0007”转换为数据类型 int 时转换失败。表别名 b 实际上是一个视图。

值“N0007”在 Workers 表中。我不明白为什么它没有从正在加入的结果中过滤出来。

编辑:

事实上,别名确实返回了正确的行 - 所以 isNumeric 正在完成这项工作。

【问题讨论】:

    标签: sql sql-server sql-server-2005 tsql


    【解决方案1】:

    我怀疑优化器试图在内部选择之前应用外部选择的 where 子句。大概它认为它能够对 Employee_ID 进行索引查找,从而在这种情况下实现更快的查询。试试:

    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 应该会处理好它。我不认为它的效率比你最初想要的要低得多,因为如果先完成非数字,无论如何都会强制进行表扫描。

    【讨论】:

    • 我也认为是优化器。其中 b.Employee_ID = CAST(empnum AS VARCHAR) 应该有帮助
    • 我尝试查看解释计划,看看我是否能发现它 - 但我并不精通阅读它们。您的查询在实际查询中运行良好。谢谢。
    • @Stanislav -- 我不确定每种类型是什么类型,所以我认为将两者都转换为 varchar 是最安全的选择。
    【解决方案2】:

    ISNUMERIC() 对于您正在尝试做的事情是出了名的不可靠。你需要an alternative, which I've been asking for here,比如this one

    【讨论】:

      【解决方案3】:

      显而易见的事情是强制比较的顺序,可能是通过从只有数字 Employee_ID 的视图中获取名称,而不是完整的 Workers 表。

      【讨论】:

      • 不幸的是,显而易见的答案是我们首先要做的事情 - 并且令人惊讶地具有相同的行为。
      【解决方案4】:

      也许 N 被认为是货币符号?您可以尝试将 IsNumeric 替换为

      LIKE REPLICATE('[0-9]',/*length of Employee_ID*/) 
      

      或者只是

      LIKE '[0-9]%' 
      

      如果字母不能在中间

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-24
        • 1970-01-01
        • 2022-09-22
        • 1970-01-01
        相关资源
        最近更新 更多