Wie erzwinge ich SQL Server 2005 zu einem vor dem, wo kommen Sie zu laufen?
-
10-07-2019 - |
Frage
Ich habe eine SQL-Abfrage bekommt, die eine Preistabelle zu einer Tabelle schließt sich mit Benutzern bereitgestellten Antworten. Meine Abfrage wird verwendet, um den Preis zu erhalten, basierend auf der eingegebenen Menge. Unten ist meine SQL-Anweisung:
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
Das Problem ist, SQL Server die where-Klausel ausgeführt wird, bevor die JOIN und es wirft den Fehler:
Fehler bei der Konvertierung, wenn die Umwandlung varchar Wert 'TEST' in dem Datentyp int.
, weil es die Min- und Max-Vergleiche tut vor dem Join ( ‚TEST‘ ist ein gültiger Benutzer eingegebene Wert in der Tabelle JobQuestion, soll aber nicht zurückgegeben werden, wenn JobQuestion zu Preis verbunden ist). Ich glaube, SQL Server ist die Wahl der WHERE weil aus irgendeinem Grund laufen meint der Parser das wäre eine effizientere Abfrage sein. Wenn ich nur laufen
SELECT JobQuestion.Value, Price.Min, Price.Max, Price.Amount FROM Price
INNER JOIN JobQuestion
ON Price.QuestionFK=JobQuestion.QuestionFK
AND JobQuestion.JobFK=1
Ich erhalte diese Ergebnisse zurück:
500 1 500 272.00
500 501 1000 442.00
500 1001 2000 782.00
Also, die WHERE Zugabe sollte die letzten zwei herauszufiltern und nur den ersten Datensatz zurück. Wie erzwinge ich SQL nur die Datensätze laufen JOIN die erste oder eine andere Technik verwenden, um herauszufiltern, die ich brauche?
Lösung
Erstens ist dies sehr wahrscheinlich Zeichen für schlechtes Design.
Wenn Sie nicht Schema ändern können, dann vielleicht könnte man dieses Verhalten erzwingen
Hinweise sind Optionen oder für die Durchsetzung angegebene Strategien von dem SQL Server-Abfrage-Prozessor auf SELECT, INSERT, UPDATE oder DELETE-Anweisungen. Die Hinweise außer Kraft setzen jeden Ausführungsplan des Abfrageoptimierer für eine Abfrage auswählen kann.
Und einige mehr:
Achtung:
Da die SQL Server-Abfrage-Optimierer in der Regel des besten Ausführungsplan für eine Abfrage auswählt, empfehlen wir, dass, und nur als letztes Mittel von erfahrenen Entwicklern und Datenbankadministratoren verwendet werden.
Andere Tipps
Versuchen Sie "Re-Formulierung" die Abfrage wie folgt:
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
Gemäß der Antwort von Christian Hayter, wenn Sie die Wahl haben, die Tabelle Design ändern =)
Sie sollten nicht Strings ints werden verglichen. Wenn Sie keinen Einfluss haben auf der ganzen Tisch-Design, dann teilen Sie die zwei verschiedenen Verwendungen der JobQuestion.Value
Spalte in zwei verschiedenen Spalten.
Falls Sie keinen Einfluss auf den Tisch Design haben - Könnten Sie versuchen, mit den Datensätze mit numerischen Werten zum Ausfiltern von ISNUMERIC ()? Ich würde, diese zu Ihrem erraten, wo Klausel helfen könnte.
Sie können die, wo wahrscheinlich entfernen ... und nur diejenigen, die als Prädikate zu Ihrem verbinden hinzuzufügen. Da ist es eine innere Verknüpfung sollte diese Arbeit
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
Sie können mit TRY_PARSE über die Strings Spalten numerisch konvertieren, und wenn SQL nicht konvertieren kann, wird es bekommen Sie statt Fehlermeldung NULL.
P. S. Diese Sache ist erstmals in SQL 2012 eingeführt, so könnte hilfreich sein.