Mehrfache Ausgabe bei SQL-Abfrage aus 2 Tabellen

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • AmicaNoctis
    antwortet
    Sieh dir mal group by an (wie gesagt) und dazu noch group_concat.

    Einen Kommentar schreiben:


  • SoS
    antwortet
    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
    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.

    JOIN ich die beiden Tabellen, ergibt sich folgendes:

    Code:
    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 UID=63 wird 1,2,3 ausgegeben
    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:


  • AmicaNoctis
    antwortet
    GROUP BY …

    Ansonsten musst du mal präziser werden und ein Beispiel wie es sein soll posten.

    Einen Kommentar schreiben:


  • SoS
    antwortet
    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 DESC
    Zuletzt geändert von SoS; 25.05.2010, 18:56.

    Einen Kommentar schreiben:


  • AmicaNoctis
    antwortet
    Zitat von SoS Beitrag anzeigen
    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.
    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.

    Einen Kommentar schreiben:


  • SoS
    antwortet
    Zitat von h3ll Beitrag anzeigen
    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.
    Das mag wohl sein, ist aber leider nicht mein Hauptproblem jetzt
    Ich glaub langsam verstanden zu haben, wieso ich so viele Rückgaben bekomme.
    Reduzieren wird den Code mal aufs wesentliche:
    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
    So bekomm ich mal korrekterweise alle LVL, die User 63 gelöst hat.
    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:


  • h3ll
    antwortet
    Zitat von SoS Beitrag anzeigen
    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).
    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.

    Einen Kommentar schreiben:


  • SoS
    antwortet
    Zitat von AmicaNoctis Beitrag anzeigen
    Hallo,

    kannst du mal bitte erläutern, was du eigentlich vor hast und die Felder den beiden Tabellen mit einer kurzen Erklärung auflisten?
    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.
    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:


  • AmicaNoctis
    antwortet
    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ß,

    Amica
    Zuletzt geändert von AmicaNoctis; 25.05.2010, 16:25.

    Einen Kommentar schreiben:


  • wahsaga
    antwortet
    Zitat von SoS Beitrag anzeigen
    was man aber mit SELECT INSTINCT abfangen kann, die Dauer der Abfrage jedoch nicht.
    Natürlich - die massive Anzahl an Datensätzen muss ja erst mal ermittelt werden, bevor überhaupt mit DISTINCT Duplikate rausgeworfen werden können.


    Informiere dich über JOINs.
    SELFHTML Artikel / Datenbanken

    Einen Kommentar schreiben:


  • h3ll
    antwortet
    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:


  • SoS
    antwortet
    Zitat von h3ll Beitrag anzeigen
    Bitte Code ordentlich und sauber formatieren. Niemand scrollt gern 2 Meter nach rechts.
    sry, dachte code bricht auch um ^^ ist behoben

    Einen Kommentar schreiben:


  • h3ll
    antwortet
    Bitte Code ordentlich und sauber formatieren. Niemand scrollt gern 2 Meter nach rechts.

    Einen Kommentar schreiben:


  • SoS
    hat ein Thema erstellt Mehrfache Ausgabe bei SQL-Abfrage aus 2 Tabellen.

    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.):
    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
    Nun will ich die Abfrage modifizieren, aber das haut irgendwie alles zusammen.
    Ich würde die Abfrage gerne wiefolgt ändern:
    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 & %')
    mit frage_solved as b..

    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,
    danke
    Zuletzt geändert von SoS; 25.05.2010, 17:19.
Lädt...
X