1

我得到了以下声明:

LEFT(f.field4, CASE WHEN PATINDEX('%[^0-9]%',f.field4) = 0 THEN LEN(f.field4) ELSE PATINDEX('%[^0-9]%',f.field4) - 1 END)=@DealNumber

并且在联系写它的人时遇到了麻烦。有人可以解释该语句的作用,以及它是否是有效的 SQL 吗?该语句的目标是将 f.field for 中的数字字符与 DealNumber 进行比较。除了 DealNumber 末尾的通配符之外,DNumber 和 DealNumber 相同。

我试图在以下语句的上下文中使用它:

SELECT d.Description, d.FileID, d.DateFiled, u.Contact AS UserFiledName, d.Pages,   d.Notes
FROM Documents AS d
LEFT JOIN Files AS f ON d.FileID=f.FileID
LEFT JOIN Users AS u ON d.UserFiled=u.UserID
WHERE SUBSTRING(f.Field8, 2, 1) = @LocationIDString
AND f.field4=@DNumber OR LEFT(f.field4, CASE WHEN PATINDEX('%[^0-9]%',f.field4) = 0 THEN LEN(f.field4) ELSE PATINDEX('%[^0-9]%',f.field4) - 1 END)=@DealNumber"

但是当我执行它时,我的代码会一直超时。

4

2 回答 2

2

CASE这是减慢速度的子句,而不是LEFT本身(尽管LEFT可能会阻止使用索引,这会产生影响)。

CASE决定了应该与什么进行比较,@DealNumber我认为它做了以下......

如果f.field4不以数字开头,请使用LEFT(f.field4, LEN(f.field4))=@DealNumber: 相当于f.field4=@DealNumber.
如果f.field4确实以数字开头,请使用{those digits}=@DealNumber.

这种计算效率不高。

我将尝试以下方法,它做出了一个很大的假设,即混合字符串可以转换为整数——也就是说,如果你转换ABC为整数,你会得到零,如果你转换,123ABC你会得到可以转换的东西,123. 我找不到任何说明这是否可能的文档。

AND f.field4=@DNumber
OR (f.field4=@DealNumber AND integer(f.field4)=0)
OR (integer(f.field4)=@DealNumber)

第一行与您的AND. 第二行f.field4=@DealNumber仅在f.field4不以数字开头时才选择。第三行选择 的初始数字部分f.field4与 相同的位置@DealNumber

As I say, there is an assumption here that integer() will work in this way. You may need to define a CAST function to do that conversion with strings. That's rather beyond me, although I would be confident that even such a function would be faster than a CASE as you currently have.

于 2012-06-14T18:33:28.623 回答
1

文档

左(str 文本,n int)

返回字符串中的前 n 个字符。当 n 为负时,返回除最后一个以外的所有 |n| 人物。

于 2012-06-14T17:43:56.057 回答