2

価格表をユーザー提供の回答を含む表に結合する 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 を実行させるか、別の手法を使用して必要なレコードだけを除外するにはどうすればよいですか?

4

6 に答える 6

4

次のように、クエリを「言い換え」てみてください。

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

クリスチャン・ヘイターからの回答によると、選択肢がある場合は、テーブルのデザインを変更してください =)

于 2009-10-29T14:33:00.783 に答える
2

文字列をintと比較するべきではありません。テーブルのデザイン全体に影響がある場合は、列の2つの異なる用途をJobQuestion.Value2つの異なる列に分割します。

于 2009-10-29T14:26:18.150 に答える
1

まず、これは設計が不十分であることを示している可能性が非常に高いです。
スキーマを変更できない場合は、 ヒントを使用してこの動作を強制できます。見積もり:

ヒントは、SELECT、INSERT、UPDATE、または DELETE ステートメントで SQL Server クエリ プロセッサによって適用されるように指定されたオプションまたは戦略です。ヒントは、クエリ オプティマイザーがクエリに対して選択する実行プランをオーバーライドします。

さらにいくつか:

注意:
通常、SQL Server クエリ オプティマイザーはクエリに最適な実行プランを選択するため、経験豊富な開発者やデータベース管理者が < join_hint>、< query_hint>、および < table_hint> を最後の手段としてのみ使用することをお勧めします。

于 2009-10-29T14:33:54.323 に答える
0

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
于 2009-10-29T14:39:28.687 に答える
0

その文字列列に対して TRY_PARSE を使用して数値に変換できます。SQL が変換できない場合は、エラー メッセージではなく NULL が返されます。

PSこれはSQL 2012で初めて導入されたので、役立つかもしれません。

于 2013-01-22T14:56:25.720 に答える
0

テーブルの設計に影響がない場合は、ISNUMERIC ()を使用して数値を含むレコードを除外してみてください。これをwhere句に追加すると役立つと思います。

于 2009-10-29T14:32:39.223 に答える