Domanda

Ho una query SQL che unisce una tabella dei prezzi a una tabella contenente le risposte fornite dall'utente. La mia query viene utilizzata per ottenere il prezzo in base alla quantità immessa. Di seguito è la mia istruzione 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

Il problema è che SQL Server sta eseguendo la clausola where prima del JOIN e sta generando l'errore:

  

Conversione non riuscita durante la conversione di   valore varchar 'TEST' per il tipo di dati int.

perché sta effettuando i confronti minimo e massimo prima del join ('TEST' è un valore immesso dall'utente valido nella tabella JobQuestion, ma non deve essere restituito quando JobQuestion è unito a Price). Credo che SQL Server stia scegliendo di eseguire WHERE perché per qualche motivo il parser ritiene che sarebbe una query più efficiente. Se ho appena eseguito

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

Ricevo questi risultati:

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

Quindi, l'aggiunta di WHERE dovrebbe filtrare gli ultimi due e restituire semplicemente il primo record. Come posso forzare SQL a eseguire prima JOIN o utilizzare un'altra tecnica per filtrare solo i record di cui ho bisogno?

È stato utile?

Soluzione

Innanzitutto, questo è molto probabilmente un segno di design scadente.
Se non riesci a modificare lo schema, forse potresti forzare questo comportamento usando hint . Citazione:

  

I suggerimenti sono opzioni o strategie specificate per l'applicazione dall'elaboratore di query di SQL Server sulle istruzioni SELECT, INSERT, UPDATE o DELETE. I suggerimenti sovrascrivono qualsiasi piano di esecuzione che Query Optimizer potrebbe selezionare per una query.

E ancora:

  

Attenzione:
  Poiché l'ottimizzatore di query di SQL Server in genere seleziona il miglior piano di esecuzione per una query, si consiglia & Lt; join_hint > ;, < query_hint > ;, e < table_hint gt &; essere utilizzato solo come ultima risorsa da sviluppatori esperti e amministratori di database.

Altri suggerimenti

Prova " riformattando " la query come segue:

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

Secondo la risposta di Christian Hayter, se hai la scelta, cambia il design della tabella =)

Non dovresti confrontare le stringhe con gli ints. Se hai qualche influenza su tutto il design della tabella, quindi dividi i due diversi usi della colonna JobQuestion.Value in due colonne diverse.

Nel caso in cui non abbia alcuna influenza sul design della tabella - Potresti provare a filtrare quei record con valori numerici usando ISNUMERIC ()? Immagino che aggiungere questo alla tua clausola where possa aiutare.

Probabilmente puoi rimuovere il dove ... e semplicemente aggiungerli come predicati al tuo join. Dato che è un join interno, questo dovrebbe funzionare

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

Puoi usare TRY_PARSE su quelle colonne di stringhe per convertire in valori numerici e, se SQL non è in grado di convertire, otterrai NULL anziché un messaggio di errore.

P.S. Questa cosa è stata introdotta per la prima volta in SQL 2012, quindi potrebbe essere utile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top