2017-07-02 2 views
-1

Ich habe diese Anfrage:SQL-Abfrage gibt manchmal falsche Ergebnisse

query = "SELECT DISTINCT set_number " + 
     "FROM next_workout_exercises " + 
     "WHERE next_id = " + workoutid + " AND exercise_number = " + exercise_number; 

und es gibt einige Ergebnisse.

Danach habe ich eine weitere Abfrage wie folgt:

query = "SELECT * FROM (SELECT * FROM next_workout_exercises INNER JOIN exercises WHERE next_workout_exercises.exercise_id = exercises.id)" + 
" WHERE next_id = " + workoutid + " AND exercise_number = " + exercise_number + " AND set_number = " + set_number; 

Und diese gibt Null zurück Ergebnisse MANCHMAL. Die Setnummer ist von der ersten Abfrage an gleich und keine Daten wurden geändert.

Kann jemand kommentieren, warum das passieren könnte?

Die Tabellen in Frage:

CREATE TABLE exercises 
(
    id    INTEGER PRIMARY KEY, 
    exercise_name TEXT, 
    explanation TEXT, 
    type   INTEGER, 
    target_body INTEGER, 
    exercise_video TEXT, 
    exercise_pic1 TEXT, 
    exercise_pic2 TEXT, 
    picturetype INTEGER, 
    backedup  INTEGER 
);  

CREATE TABLE next_workout_exercises 
(
    id    INTEGER PRIMARY KEY, 
    next_id   INTEGER, 
    exercise_id  INTEGER, 
    weightkg  REAL, 
    weightlb  REAL, 
    reps   INTEGER, 
    reps2   INTEGER, 
    set_number  INTEGER, 
    exercise_number INTEGER, 
    incrementkg  REAL, 
    incrementlb  REAL, 
    resttime1  INTEGER, 
    resttime2  INTEGER, 
    resttime3  INTEGER, 
    failures  INTEGER, 
    failuresallowed INTEGER, 
    percentage  REAL, 
    reptype   INTEGER, 
    exercisetype INTEGER, 
    backedup  INTEGER, 
    FOREIGN KEY(next_id) REFERENCES nextWorkout(id), 
    FOREIGN KEY(exercise_id) REFERENCES exercises(id) 
); 
+0

Können Sie Ihre Frage bearbeiten, um die Tabellenschemas einzuschließen und einen minimalen Satz von Daten in den Tabellen bereitzustellen, der das falsche Verhalten zeigt, das Sie haben? – CDahn

+0

@CDahn schlug mich dazu :) – Jim

+0

Sorry. Ich habe die Tabellen hinzugefügt. – Mizan

Antwort

0

Wenn (a) niemand die Daten zu modifizieren, (b) Ihre zweite Abfrage die gleichen Werte für workoutid und exercise_number verwendet, und (c) Ihre zweite Abfrage verwendet Die von der ersten Abfrage zurückgegebene set_number muss dann wahr sein, dass Ihre falsch angegebene Join-Bedingung der Grund ist, warum Sie nur manchmal die gewünschten Daten erhalten.

Sie geben eine Bedingung wie folgt verbinden:

ON next_workout_exercises.exercise_id = exercises.id 

Sie nicht verwenden eine WHERE-Klausel die Verbindung zu tun, wenn Sie Ihre Verknüpfung mit traditionellen Mitteln zu schreiben.

Ein prägnanter Weise die zweite Abfrage zu schreiben, ist dies:

SELECT n.*, e.* 
FROM next_workout_exercises n 
INNER JOIN exercises e ON n.exercise_id = e.id 
WHERE n.next_id = :workoutid 
AND n.exercise_number = :exercise_number 
AND n.set_number = :set_number 

Oh, und bitte machen Sie Ihre DBA einen Gefallen, indem Platzhalter verwenden. Das sieht nach einem idealen Code aus, um sie zu verwenden.

+0

Die 'where'-Klausel ist semantisch äquivalent zur 'on'-Anweisung, da sie die Ausgabe einschränkt. Es ist möglicherweise nicht so effizient, abhängig von DBMS. Im schlimmsten Fall produziert sein 'INNER JOIN' das volle kartesische Produkt beider Tische, und das WHERE legt alles weg, was er nicht will. Wie auch immer, das "on", das Sie ihm zur Verfügung gestellt haben, soll ihm die gleiche Ausgabe wie sein 'wo' liefern. – CDahn

+0

Vielen Dank. Dies könnte nur das Problem sein. Ich werde es ausprobieren und zu dir zurückkommen. Danke für die Hilfe! – Mizan

+0

@Mizan werfen Sie einen Blick auf diese anderen ausgezeichneten SO-Fragen, um die Relevanz von "ON" gegenüber "WO" zu sehen: [1] (https://stackoverflow.com/questions/1613304/ansi-joins-versus-where-clause -joins), [2] (https://stackoverflow.com/questions/1018822/inner-join-on-vs-where-clause) und [3] (https://stackoverflow.com/questions/354070/ sql-join-where-Klausel-vs-on-Klausel). – CDahn

0

Es scheint, dass Ihr Datensatz keine Zeile in next_workout_exercises enthält, die eine next_id und exercise_number für die set_number Sie verwenden in der zweiten Abfrage enthält.

Ihre erste Abfrage sagt nur: „Gib mir alle eindeutigen set_number Werte aus der Tabelle“ aber nicht nicht garantieren, dass die set_number Sie in der zweiten Abfrage sind die Angabe von dem einzigartigen Satz von den ersten ist Abfrage.

+0

Nein, ich habe überprüft und die zweite Abfrage verwendet die Satznummern, die in der ersten vorhanden sind. – Mizan

+0

@Mizan Beispieldaten oder es ist nicht geschehen. – CDahn

Verwandte Themen