2012-06-14 136 views
1

我得到了如下聲明:當與JOIN不配對時,SQL中的LEFT會做什麼?它爲什麼會導致我的查詢超時?

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

時遇到麻煩寫它的人接觸。有人可以解釋一下該語句的作用,以及它是否是有效的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 [email protected] OR LEFT(f.field4, CASE WHEN PATINDEX('%[^0-9]%',f.field4) = 0 THEN LEN(f.field4) ELSE PATINDEX('%[^0-9]%',f.field4) - 1 END)[email protected]" 

,但我的代碼一直超時,當我執行它。

回答

2

這是CASE條款,是速度變慢,無法LEFT本身(儘管LEFT可能阻止使用索引,這將產生效果)。

CASE決定什麼應該@DealNumber相比較,我認爲它的下面...

如果f.field4不以數字開頭,使用LEFT(f.field4, LEN(f.field4))[email protected]:這相當於[email protected]
如果f.field4確實以數字開頭,請使用{those digits}[email protected]

這種計算方式效率不高。

我會嘗試以下,這使得假設混合字符串可以轉換爲整數—也就是說,如果轉換ABC你獲得零,和一個整數,如果你轉換123ABC你什麼可以轉換,123。我找不到任何文件說明這是否可行。

AND [email protected] 
OR ([email protected] AND integer(f.field4)=0) 
OR (integer(f.field4)[email protected]) 

第一行與您的AND相同。第二行僅在f.field4未以數字開頭時選擇[email protected]。第三行選擇f.field4的初始數字部分與@DealNumber相同的位置。

正如我所說,這裏有一個假設,integer()將以這種方式工作。您可能需要定義一個CAST函數來使用字符串進行轉換。這超出了我的範圍,儘管我相信即使這樣的功能會比目前的CASE更快。

+0

感謝您的解釋! –

1

doc

左(海峽文本,正INT)

返回字符串中前n個字符。當n爲負時,返回除最後一個| n |之外的所有內容字符。

+0

這是Postgre SQL。那是一樣的嗎?具體來說,這爲什麼會影響性能? –

+0

我經常不使用Postgre,但它看起來像你問過的表達式必須應用到結果的每一行。這可能很慢。 – raina77ow

+0

這當然可以成爲它的一部分。儘管如此,我覺得在C#的cmd.Parameters.AddWithValue()方法中使用通配符也有問題。 –

相關問題