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の数字をDealNumberと比較することです。DNumberとDealNumberは、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ではなく、物事を遅くしているのは句です(ただし、効果があるインデックスの使用を妨げる可能性があります)。LEFTLEFT

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です。2 行目は、数字で始まらないf.field4=@DealNumber場合にのみ選択します。f.field43 行目は、 の最初の数値部分がf.field4と同じ場所を選択し@DealNumberます。

私が言ったように、ここにはこのように機能する仮定がありますinteger()CAST文字列でその変換を行うには、関数を定義する必要がある場合があります。CASEそのような関数でさえ、現在持っているよりも高速になると確信していますが、それは私を超えています。

于 2012-06-14T18:33:28.623 に答える
1

ドキュメントから:

left(str テキスト, n int)

文字列の最初の n 文字を返します。n が負の場合、最後の |n| を除くすべてを返します。文字。

于 2012-06-14T17:43:56.057 に答える