Sql server 我认为WHERE子句的项目顺序无关紧要,为什么它在我的代码中很重要?

Sql server 我认为WHERE子句的项目顺序无关紧要,为什么它在我的代码中很重要?,sql-server,tsql,Sql Server,Tsql,这不起作用: SELECT CAST(o.OrderNo AS INT) AS [OrderNo], DATEADD(d, 7, CAST(SUBSTRING(o.User_Memo1, CHARINDEX('Pack',o.User_Memo1)+5, 8) AS DATE)) AS [1 Week After Prod Due], o.User_Date1 AS [3 Week Ack Date] FROM Orders o JOIN Ord

这不起作用:

SELECT
    CAST(o.OrderNo AS INT) AS [OrderNo], 
    DATEADD(d, 7, CAST(SUBSTRING(o.User_Memo1, 
    CHARINDEX('Pack',o.User_Memo1)+5, 8) AS DATE)) AS [1 Week After Prod Due],
    o.User_Date1 AS [3 Week Ack Date]  
FROM Orders o 
    JOIN OrderDet od ON o.OrderNo = od.OrderNo
    LEFT JOIN DelTicket d ON o.OrderNo = d.OrderNo
WHERE CONVERT(VARCHAR(MAX), o.User_Memo1) IS NOT NULL
    AND o.User_Date1 IS NULL
    AND DATEADD(d, -24, DATEADD(d, 7, CAST(SUBSTRING(o.User_Memo1, 
    CHARINDEX('Pack',o.User_Memo1)+5, 8) AS DATE))) < CAST(GETDATE() AS DATE)
    AND SUBSTRING(o.User_Memo1, 1, 3) = 'Cut'
GROUP BY o.OrderNo, DATEADD(d, 7, CAST(SUBSTRING(o.User_Memo1, 
CHARINDEX('Pack',o.User_Memo1)+5, 8) AS DATE)), o.User_Date1, o.User_Date2, 
o.User_Number2, d.ShipDate, o.User_Number3
ORDER BY DATEADD(d, 7, CAST(SUBSTRING(o.User_Memo1, 
CHARINDEX('Pack',o.User_Memo1)+5, 8) AS DATE)) DESC;
我得到这个错误:

从字符串转换日期和/或时间时转换失败。>

如果我把这个项目:

    AND DATEADD(d, -24, DATEADD(d, 7, CAST(SUBSTRING(o.User_Memo1, 
CHARINDEX('Pack',o.User_Memo1)+5, 8) AS DATE))) < CAST(GETDATE() AS DATE)
在WHERE子句的末尾,它按预期完美运行。在用户备忘录1中没有“剪切”的项目确实应该无法转换。然而,我读到顺序并不重要。所以我很困惑

编辑:使用屏幕截图更新


理论上,顺序并不重要。然而,对于复杂的查询,查询优化器可能会遵循不同的路径,并导致不同的执行计划。这对于具有多个联接的查询是典型的。更改联接顺序时,执行计划的形状可能会更改。我想这可能是因为同一个问题。尝试检查两个选项的估计执行计划,看看它们是否有所不同


当您将有问题的谓词放在WHERE子句的末尾时。执行计划不同,只是Microsoft知道原因,导致错误的问题行在转换之前被过滤掉。

您很幸运。关键是您无法控制谓词执行的顺序。在您的情况下,它恰好以与代码相同的顺序运行。即使在同一张桌子上,情况也并非总是如此。如果行数发生了变化,甚至统计数据发生了微小的变化,那么查询引擎下次可能会以不同的顺序处理谓词。好吧,这不应该发生……所以我认为在代码运行之间会发生其他变化。我同意拉马克的观点。你能发布一个完全重现这个问题的脚本吗?如果不是,我必须怀疑你所说的正在发生的事情。我添加了截图,如果你使用SQL Server 2012或更高版本,你可以考虑将你的CAST语句更改为TyySCAST。无论执行顺序如何,它都会保持运行。