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가 조인 전에 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에 처음 소개되었으므로 도움이 될 수 있습니다.