Mehrfache Ausgabe bei SQL-Abfrage aus 2 Tabellen
Einklappen
X
-
Für den User SoS mit der ID 63 sollte nun 1,2,3 aus frage angezeigt werden, weil er diese gesolved hat, und 2,4,5 weil er diese eingestellt hat.Code:frage ID | ... | Einsteller 1 Max 2 SoS 3 Tom 4 SoS 5 SoS frage_solved UID | LVL 63 1 63 2 63 3 50 1 50 2 50 3 50 4 50 5
JOIN ich die beiden Tabellen, ergibt sich folgendes:
Aufgrund von UID=63 wird 1,2,3 ausgegebenCode:UID | LVL/ID | Einsteller 63 1 Max 63 2 SoS 63 3 Tom 50 1 Max 50 2 SoS 50 3 TOm 50 4 SoS 50 5 SoS SELECT * FROM frage a INNER JOIN frage_solved b ON (a.ID = b.LVL) WHERE b.UID = '63' OR a.einsteller = 'SoS' ORDER BY ID DESC
Aufgrund von Einsteller = SoS wird 2,2,4,5 ausgegeben.
In diesem Bsp wird jetzt nur ein Wert zuviel ausgegeben, aber in der Praxis, ist es leider um vielfaches mehr. Ein reduzieren mittels DISTINCT liefert zwar das gewünschte Ergebnis, aber es wird leider zulange gebraucht dafür, da der Einsteller eines LVL bei jedem User gezählt wird..
Mach ich noch was falsch?
PS: Formatierung leider bissl doof...
Einen Kommentar schreiben:
-
GROUP BY …
Ansonsten musst du mal präziser werden und ein Beispiel wie es sein soll posten.
Einen Kommentar schreiben:
-
Im Code kommt die entsprechende Spalte doch garnicht mehr vor.
Dennoch aber die riesige Mehrfachausgabe jeder Zeile. Wie kann ich dem jetzt entgegen wirken?
Code:SELECT * FROM frage a INNER JOIN frage_solved b ON (a.ID = b.LVL) WHERE b.UID = '63' OR a.einsteller = 'SoS' ORDER BY ID DESCZuletzt geändert von SoS; 25.05.2010, 18:56.
Einen Kommentar schreiben:
-
Nein, aufgrund des schlechten Designs, denn eigentlich könnte man das prima filtern bzw. gruppieren. Da du dich aber weigerst, das als Ursache anzuerkennen, wirst du mit der schlechten Performance leben müssen.Zitat von SoS Beitrag anzeigenDie 2. Bedingung jedoch wirft mir jedes LVL, das die Bedingung erfüllt, mehrfach raus, da das LVL ja für jeden User usw da steht, aufgrund des JOINS.
Einen Kommentar schreiben:
-
Das mag wohl sein, ist aber leider nicht mein Hauptproblem jetztZitat von h3ll Beitrag anzeigenEin grober Fehler im Datenbankdesign. In einer Spalte sollte nicht mehr als eine Information stehen. Das macht das ganze natürlich unnötig kompliziert und performance-aufwändig.
Ich glaub langsam verstanden zu haben, wieso ich so viele Rückgaben bekomme.
Reduzieren wird den Code mal aufs wesentliche:
So bekomm ich mal korrekterweise alle LVL, die User 63 gelöst hat.Code:SELECT * FROM frage a INNER JOIN frage_solved b ON (a.ID = b.LVL) WHERE b.UID = '63' OR a.einsteller = 'SoS' ORDER BY ID DESC
Die 2. Bedingung jedoch wirft mir jedes LVL, das die Bedingung erfüllt, mehrfach raus, da das LVL ja für jeden User usw da steht, aufgrund des JOINS.
Kann man nicht irgendwie die beiden Abfragen getrennt voneinander machen, und das Ergebnis wieder zusammenfügen? Einzeln funktionieren die Abfragen nämlich wunderbar und ohne Auslastung.
Bsp: (Pseudocode)
Code:SELECT * FROM frage a WHERE a.einsteller = 'SoS' AND SELECT a.* FROM frage a, frage_solved b WHERE b.UID='63' AND a.ID = b.LVL
Einen Kommentar schreiben:
-
Ein grober Fehler im Datenbankdesign. In einer Spalte sollte nicht mehr als eine Information stehen. Das macht das ganze natürlich unnötig kompliziert und performance-aufwändig.Zitat von SoS Beitrag anzeigenDies steht in frage unter "ersteller". Problem hier, er kann alleine oder zumehrt drinnen stehen, wo sie mit " & " getrennt sind. Ist er zumehr drinnen, kann er am Anfang stehen (USER & %), in der Mitte (% & USER & %) oder am Ende (% & USER).
Einen Kommentar schreiben:
-
Also, ich hatte bis jetz immer LVL_max gespeichert, und alle LVL darunter ausgegeben. Da die LVL nun aber nicht mehr der Reihe nach gemacht werden, muss ich für jedes LVL extra Speichern, ob USER das schon gelöst hat.Zitat von AmicaNoctis Beitrag anzeigenHallo,
kannst du mal bitte erläutern, was du eigentlich vor hast und die Felder den beiden Tabellen mit einer kurzen Erklärung auflisten?
Dazu wird in frage_solved die User-ID in UID und das entsprechende LVL gespeichert.
Danach sollen die LVL abgefragt werden, die schon von USER gelöst wurden, also in frage_solved als UID|LVL vorkommen.
Zudem sollen noch die LVL angezeigt werden, die von ihm erstellt wurden.
Dies steht in frage unter "ersteller". Problem hier, er kann alleine oder zumehrt drinnen stehen, wo sie mit " & " getrennt sind. Ist er zumehr drinnen, kann er am Anfang stehen (USER & %), in der Mitte (% & USER & %) oder am Ende (% & USER). Wenn ihr hierführ eine bessere Abfrage wisst, bin ich gerne dafür offen
Die LVL sind in frage gespeichert und haben id als ID.
Ich hoffe, das ist halbwegs verständlich.
Ich probier nebenbei schon mit Joins rum jetz, danke
Einen Kommentar schreiben:
-
Hallo,
kannst du mal bitte erläutern, was du eigentlich vor hast und die Felder den beiden Tabellen mit einer kurzen Erklärung auflisten? Die create-table-Statements könnten auch schon helfen.
Übrigens: Wenn du etwas mit LIKE vergleichst, ohne Platzhalter zu verwenden, solltest du lieber gleich = nehmen.
Gruß,
AmicaZuletzt geändert von AmicaNoctis; 25.05.2010, 16:25.
Einen Kommentar schreiben:
-
Natürlich - die massive Anzahl an Datensätzen muss ja erst mal ermittelt werden, bevor überhaupt mit DISTINCT Duplikate rausgeworfen werden können.Zitat von SoS Beitrag anzeigenwas man aber mit SELECT INSTINCT abfangen kann, die Dauer der Abfrage jedoch nicht.
Informiere dich über JOINs.
SELFHTML Artikel / Datenbanken
Einen Kommentar schreiben:
-
Mach einen sauberen INNER JOIN.
Die Theta-Style schreibweise ist schwer lesbar und verleitet zu Fehlern. Im blödesten Fall machst du einen Cross-Join und die Ergebnismenge vervielfacht sich.
Code:SELECT t1.foo, t2.bar FROM tabelle1 t1 INNER JOIN tabelle2 t2 ON ( t2.id = t1.fremd_id ) WHERE t1.foo > 1 AND t2.bar LIKE 'abc%'
Zuletzt geändert von h3ll; 25.05.2010, 16:22.
Einen Kommentar schreiben:
-
sry, dachte code bricht auch um ^^ ist behobenZitat von h3ll Beitrag anzeigenBitte Code ordentlich und sauber formatieren. Niemand scrollt gern 2 Meter nach rechts.
Einen Kommentar schreiben:
-
Bitte Code ordentlich und sauber formatieren. Niemand scrollt gern 2 Meter nach rechts.
Einen Kommentar schreiben:
-
Mehrfache Ausgabe bei SQL-Abfrage aus 2 Tabellen
Hallo, ich hab eine Frage.
Ich habe zwei Tabellen:
fragen (ca 500 Einträge) und fragen_solved (ca 40.000 Einträge)
Meine Abfrage bisher lautete (Bsp.):
Nun will ich die Abfrage modifizieren, aber das haut irgendwie alles zusammen.Code:SELECT a.ID, a.Ersteller, a.Frage_QT, a.LVL_Code, a.erster, a.tester FROM frage a WHERE a.ID < 101 OR a.erster LIKE 'NICK' OR (a.Ersteller LIKE 'NICK' OR a.Ersteller LIKE 'NICK & %' OR a.Ersteller LIKE '% & NICK' OR a.Ersteller LIKE '% & NICK & %') ORDER BY ID DESC
Ich würde die Abfrage gerne wiefolgt ändern:
mit frage_solved as b..Code:WHERE (a.ID = b.LVL AND b.UID = 'NICK') OR (a.`Ersteller` LIKE 'NICK' OR a.`Ersteller` LIKE 'NICK & %' OR a.`Ersteller` LIKE '% & NICK' OR a.`Ersteller` LIKE '% & NICK & %')
Die Abfrage dauert ewig lang, und liefert ca 1.000.000+ Einträge, anstatt ca 150, was man aber mit SELECT INSTINCT abfangen kann, die Dauer der Abfrage jedoch nicht.
Nach probieren bin ich drauf gekommen, dass bei der ersten Abfrage, wenn ich FROM frage a, frage_solved b hinschreibe, ohne dass auf b eine Bedingung oder Ausgabe zutrifft, sich die Abfrage seehr verlängert, und die Ausgaben wieder mehrfach vorkommen und in die Millionen gehen.
Das zwingt natürlich meinen Server in die Knie und ist sicher nicht ideal, leider kann ich aber keinen Fehler entdecken, vor allem den Grund nicht, wieso sich dieselbe Abfrage (die 1.) so verlängert/ändert, wenn ich einfach eine Tabelle dazuschreibe, die zwar viele Einträge hat, aber nicht in die Abfrage weiters eingreift. Wäre toll, wenn mir wer helfen könnte,
dankeZuletzt geändert von SoS; 25.05.2010, 17:19.Stichworte: -
Einen Kommentar schreiben: