我收到了以下声明:
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中的数字字符与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"
但是当我执行它时,我的代码会保持超时。
答案 0 :(得分: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
相同的位置。
正如我所说,这里假设integer()
将以这种方式运作。您可能需要定义CAST
函数以使用字符串进行转换。这远远超出了我,尽管我相信即使这样的功能也会比你现在拥有的CASE
更快。
答案 1 :(得分:1)
来自doc:
left(str text,n int)
返回字符串中的前n个字符。当n为负数时,返回除最后| n |之外的所有内容字符。