Pergunta

Eu tenho uma consulta SQL que se junta a uma tabela de preços para uma tabela contendo as respostas fornecidas pelo usuário. Minha pergunta é usado para obter o preço baseado na quantidade inserida. Abaixo está a minha declaração 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

O problema é SQL Server está em execução a cláusula WHERE antes da JOIN e ele está jogando o erro:

A conversão falhou ao converter o valor varchar 'teste' para tipo de dados int.

porque ele está fazendo o min e comparações máximo antes da junção ( 'teste' é um usuário válido valor inserido na tabela de JobQuestion, mas não deve ser devolvido quando JobQuestion se une ao preço). Eu acredito que o SQL Server está escolhendo para executar o ONDE porque, por algum motivo, o analisador pensa que seria uma consulta mais eficiente. Se eu executar

SELECT JobQuestion.Value, Price.Min, Price.Max, Price.Amount FROM Price
    INNER JOIN JobQuestion 
        ON Price.QuestionFK=JobQuestion.QuestionFK
        AND JobQuestion.JobFK=1

Eu recebo estes resultados de volta:

500 1       500     272.00
500 501     1000    442.00
500 1001    2000    782.00

Assim, adicionando o ONDE deve filtrar os dois últimos e apenas retornar o primeiro registro. Como faço para forçar o SQL para executar o JOIN primeiro ou usar outra técnica para filtrar apenas os registros que eu preciso?

Foi útil?

Solução

Em primeiro lugar, este é muito provável sinal de má concepção.
Se você não pode mudar o esquema, então talvez você poderia forçar este comportamento usando dicas . Citação:

Sugestões são opções ou estratégias específicas para a aplicação pelo processador de consulta SQL Server em SELECT, INSERT, UPDATE, ou instruções DELETE. As sugestões substituir qualquer plano de execução do otimizador de consulta pode seleccionar para uma consulta.

E um pouco mais:

Atenção:
Porque o otimizador de consulta SQL Server normalmente seleciona o melhor plano de execução para uma consulta, recomendamos que , e ser usado apenas como um último recurso por desenvolvedores experientes e administradores de banco de dados.

Outras dicas

Tente "re-fraseado" a consulta da seguinte maneira:

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

De acordo com a resposta de Christian Hayter, se você tem a opção, mudar o design da tabela =)

Você não deve estar comparando cordas para ints. Se você tem alguma influência em todo o design da tabela, em seguida, dividir os dois usos diferentes da coluna JobQuestion.Value em duas colunas diferentes.

No caso de você não tem nenhuma influência sobre o design da tabela - Você poderia tentar para filtrar os registros com valores numéricos usando IsNumeric ()? Eu acho adicionando isso ao seu onde cláusula poderia ajudar.

Você pode provavelmente remover o onde ... e apenas adicionar aqueles como predicados a sua juntar-se. Desde que é participar de um interior isso deve funcionar

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

Você pode usar TRY_PARSE mais que as cordas colunas para converter para numérico, e se SQL não pode converter, ele vai te nulo em vez de mensagem de erro.

P.S. Esta coisa é primeira vez introduzido no SQL 2012, por isso pode ser útil.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top