SQL Server 2005で強制的に場所の前に結合を実行するにはどうすればよいですか?
-
10-07-2019 - |
質問
価格設定テーブルをユーザー指定の回答を含むテーブルに結合するSQLクエリがあります。私のクエリは、入力された数量に基づいて価格を取得するために使用されます。以下は私のSQLステートメントです。
SELECT JobQuestion.Value, Price.Min, Price.Max, Price.Amount FROM Price
INNER JOIN JobQuestion
ON Price.QuestionFK=JobQuestion.QuestionFK
AND JobQuestion.JobFK=1
WHERE Price.Min <= JobQuestion.Value
AND Price.Max >= JobQuestion.Value
問題は、SQL ServerがJOINの前にwhere句を実行しており、エラーをスローしていることです:
変換時に変換に失敗しました varchar値 'TEST'からデータ型int。
結合前に最小と最大の比較を行っているため(「TEST」はJobQuestionテーブルにユーザーが入力した有効な値ですが、JobQuestionがPriceに結合されたときに返されるべきではありません)。何らかの理由でパーサーがそれがより効率的なクエリだと考えるので、SQL ServerはWHEREの実行を選択していると思います。実行するだけの場合
SELECT JobQuestion.Value, Price.Min, Price.Max, Price.Amount FROM Price
INNER JOIN JobQuestion
ON Price.QuestionFK=JobQuestion.QuestionFK
AND JobQuestion.JobFK=1
これらの結果が返されます:
500 1 500 272.00
500 501 1000 442.00
500 1001 2000 782.00
したがって、WHEREを追加すると最後の2つが除外され、最初のレコードが返されます。 SQLにJOINを最初に実行させるか、別の手法を使用して必要なレコードのみを除外するにはどうすればよいですか?
解決
最初に、これはデザインの質が低い可能性が高いことを示しています。
スキーマを変更できない場合は、ヒント。引用:
ヒントは、SELECT、INSERT、UPDATE、またはDELETEステートメントでSQL Serverクエリプロセッサが実施するために指定されたオプションまたは戦略です。ヒントは、クエリオプティマイザーがクエリに対して選択する可能性のある実行プランを上書きします。
その他:
注意:
SQL Serverクエリオプティマイザーは通常、クエリに最適な実行プランを選択するため、<!> lt;をお勧めします。 join_hint <!> gt;、<!> lt; query_hint <!> gt;および<!> lt; table_hint <!> gt;経験豊富な開発者とデータベース管理者が最後の手段としてのみ使用してください。
他のヒント
<!> quot; re-phrasing <!> quot;をお試しください。次のようなクエリ:
SELECT *
FROM (
SELECT JobQuestion.Value,
Price.Min,
Price.Max,
Price.Amount
FROM Price
INNER
JOIN JobQuestion
ON Price.QuestionFK = JobQuestion.QuestionFK
AND JobQuestion.JobFK = 1
) SQ
WHERE SQ.Min <= SQ.Value
AND SQ.Max >= SQ.Value
Christian Hayterの回答によると、選択があれば、テーブルのデザインを変更する=)
文字列をintと比較するべきではありません。テーブルデザインに何らかの影響がある場合は、JobQuestion.Value
列の2つの異なる使用法を2つの異なる列に分割します。
テーブルのデザインに影響がない場合- ISNUMERIC ()?これをwhere句に追加すると役立つと思います。
where ...を削除して、結合に述語として追加するだけです。内部結合なので、これは動作するはずです
SELECT JobQuestion.Value, Price.Min, Price.Max, Price.Amount
FROM Price
INNER JOIN JobQuestion
ON Price.QuestionFK=JobQuestion.QuestionFK
AND JobQuestion.JobFK=1
AND Price.Min <= JobQuestion.Value
AND Price.Max >= JobQuestion.Value
その文字列列に対してTRY_PARSEを使用して数値に変換できます。SQLが変換できない場合、エラーメッセージではなくNULLが返されます。
PSこれはSQL 2012で初めて導入されたものなので、役に立つかもしれません。