Mehrfache Ausgabe bei SQL-Abfrage aus 2 Tabellen

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

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

    Leave a comment:


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

    Leave a comment:


  • AmicaNoctis
    replied
    GROUP BY …

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

    Leave a comment:


  • SoS
    replied
    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
    Last edited by SoS; 25-05-2010, 18:56.

    Leave a comment:


  • AmicaNoctis
    replied
    Originally posted by SoS View Post
    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.

    Leave a comment:


  • SoS
    replied
    Originally posted by h3ll View Post
    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

    Leave a comment:


  • h3ll
    replied
    Originally posted by SoS View Post
    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.

    Leave a comment:


  • SoS
    replied
    Originally posted by AmicaNoctis View Post
    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

    Leave a comment:


  • AmicaNoctis
    replied
    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
    Last edited by AmicaNoctis; 25-05-2010, 16:25.

    Leave a comment:


  • wahsaga
    replied
    Originally posted by SoS View Post
    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

    Leave a comment:


  • h3ll
    replied
    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%'
    Last edited by h3ll; 25-05-2010, 16:22.

    Leave a comment:


  • SoS
    replied
    Originally posted by h3ll View Post
    Bitte Code ordentlich und sauber formatieren. Niemand scrollt gern 2 Meter nach rechts.
    sry, dachte code bricht auch um ^^ ist behoben

    Leave a comment:


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

    Leave a comment:


  • SoS
    started a topic 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
    Last edited by SoS; 25-05-2010, 17:19.
Working...
X