문제

가격 테이블을 사용자가 제공 한 답변이 포함 된 테이블에 합류하는 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가 조인 전에 WHERE 절을 실행하고 있으며 오류를 던지고 있다는 것입니다.

Varchar 값 '테스트'를 데이터 유형 int로 변환 할 때 변환이 실패했습니다.

가입 전에 Min and Max 비교를 수행하기 때문에 ( '테스트'는 JobQuestion 테이블에서 유효한 사용자 입력 값이지만 JobQuestion이 가격에 가입 할 때 반환해서는 안됩니다). SQL Server가 어떤 이유로 든 파서가 더 효율적인 쿼리라고 생각하기 때문에 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

따라서 마지막 두 개를 필터링 해야하는 곳을 추가하고 첫 번째 레코드를 반환하십시오. SQL이 조인을 먼저 실행하거나 다른 기술을 사용하여 필요한 레코드 만 필터링하도록 강요하려면 어떻게해야합니까?

도움이 되었습니까?

해결책

첫째, 이것은 디자인이 좋지 않은 징후 일 가능성이 높습니다.
스키마를 변경할 수 없다면이 동작을 사용하여 힌트. 인용하다:

힌트는 select, insert, update 또는 delete 문의 SQL Server 쿼리 프로세서에서 시행에 지정된 옵션 또는 전략입니다. 힌트는 쿼리 최적화가 쿼리를 선택할 수있는 실행 계획을 무시합니다.

그리고 좀 더 :

주의:
SQL Server Query Optimizer는 일반적으로 쿼리에 대한 최상의 실행 요금제를 선택하므로 숙련 된 개발자 및 데이터베이스 관리자가 <tern_hint>, <query_hint> 및 <pable_hint>를 최종 수단으로 만 사용하는 것이 좋습니다.

다른 팁

다음과 같이 쿼리를 "repphrasing"시도하십시오.

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의 답변에 따라 선택의 여지가 있다면 테이블 디자인을 변경하십시오 =)

문자열을 ints와 비교해서는 안됩니다. 테이블 디자인에 전혀 영향을 미치면 두 가지 다른 용도를 분할하십시오. JobQuestion.Value 두 개의 다른 열로 열입니다.

테이블 디자인에 영향을 미치지 않는 경우 - 해당 레코드를 사용하여 해당 레코드를 필터링하려고 노력할 수 있습니까? isnumeric()? 나는 당신의 위치에 도움이 될 수있는 곳에 이것을 추가하는 것 같아요.

당신은 어디를 제거 할 수 있습니다 ... 내부 가입이기 때문에 이것은 작동해야합니다

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을 얻을 수 있습니다.

추신 : 이것은 SQL 2012에 처음 소개되었으므로 도움이 될 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top