Datenbankabfragen in Schleifen?



  • Hi Leute,
    ich habe Probleme bei der Entwicklung einer richtigen, leistungsorientierten, Lösung.
    Es geht darum, aus einer Datenbank ein User mit dem anderen zu vergleichen und die Übereinstimmungen zu bewerten.

    Die Tabelle Relation_User_Produkt:

    UserID | ProduktID | Note
    -------+-----------+------
    6 88 3
    6 11 5
    3 22 2
    1 11 1
    1 22 1
    6 22 3

    Hier mein Pseudo-Pseudocode 😉 :

    function vergleicheUserbewertung(int MainUserID) { // mit diesem User sollen die anderen verglichen werden 
    	int anzahlUebereinstimmungen[dieuserid] = 0;
    	int notensumme[dieuserid] = 0;
    	int Differenz = 0;
    	while(noch ein eintrag in der tabelle mit MainUserID vorhanden) {
    		hole die nächste Produktid und Note des MainUserID
    		abfrage der ProduktID und Note von MainUserID.
    		while(noch Einträge mit der Produktid vorhanden) {
    			abfrage der Note und UserID
    			Differenz errechnen:
    			Differenz = Note_MainUserID - Note_UserID (soll immer positiv sein)
    			notensumme[UserID] += Differenz
    			anzahlUebereinstimmungen[UserId] += 1;
    
    		}
    	}
            uebereinstimmungdesUsers[UserID] = notensumme[UserID] / anzahlUebereinstimmungen[UserId] 
    // hier dann das erhoffte ergebniss
    }
    

    Kann man das ganz noch anders lösen?
    Es ist doch keine gute Ideen datenbankabfragen in schleifen zu packen oder?



  • Wahrscheinlich hab ich es falsch verstanden 😃 aber womöglich hilft es doch weiter. So wie ich es sehe, willst du die Produkte von 2 Personen vergleichen, die beide dieses Produkt haben um daraus den Notendurchschnitt zu errechnen?

    SELECT
        produktid AS prid
      , SUM(note) AS summe
      , COUNT(produktid) AS anzahl
      , AVG(note) AS schnitt
    FROM
        relation_user_produkt
    WHERE
        userid IN(1, 6)
    GROUP BY
        produktid
    HAVING
        anzahl > 1
    

    Vielleicht sind ein paar Ansätze dabei, die helfen.



  • sind wir hier im sql forum oda was



  • no_cot schrieb:

    sind wir hier im sql forum oda was

    Das hilft niemand.
    Entweder du verschiebst den Fred ins richtige Forum, was du nicht kannst, weil du kein Mod bist 😃 ätsch
    Oder du bringst nen fachlichen sinnigen Beitrag 😉



  • Danke BasicMan,

    im Grunde ist das schon richtig, aber ich will person A mit ALLEN anderen vergleichen, nicht nur mit einem.

    Des weiteren soll die Differenz der Noten berechnet werden.

    zb:
    gerade ist die sql abfrage dabei nur den HauptUser mit einem zu vergleichen:
    2 Treffer gibt es nur:
    Produkt x und y.
    Der gefundene User hat beides mit einer 4 bewertet,
    der Hauptuser mit einer 1.
    Also soll gerechnet werden:
    x - x' + y - y' / 2 (da 2 produkte)
    4 - 1 + 4 - 1 / 2 = 3

    Die Abfrage soll mir nun die ID des Users liefern, mit dem da verglichen wurde + den Notendurchschnitt (3). Und das mit allen Usern.

    Sorry fürs falsche Forum, dachte aber nicht, dass man es rein mit SQL lösen kann. (wie gesagt, datenbank nap :D)



  • SELECT
        *
        -- Was wenn im folgenden ein negativer Wert rauskommt?
        , subUser.note - mainUser.note AS diff
    FROM
        test.relation_user_produkt AS mainUser
    INNER JOIN test.relation_user_produkt AS subUser ON subUser.produktid = mainUser.produktid
        AND subUser.userid <> 1
    WHERE mainUser.userid = 1
    

    Ich liefer noch mal einen Ansatz, der den aktuellen User mit allen anderen Usern vergleicht. (wo beide User Übereinstimmungen bei den Produkte besitzen)
    Darauf aufbauend kann man natürlich noch gruppieren ect.



  • 🙂 Du bist echt super (:

    Wenns negativ ist, solls zum positiven gemacht werden.
    Also betragsstriche. Das kann man unter sql aber wohl icht machen, nich?

    Darauf aufbauend kann man natürlich noch gruppieren ect.

    Was meinst du mir gruppieren?



  • Das Problem mit dem negativen Wert kannst z.B. mit nem CASE lösen.
    Gibt eventuell auch bessere Möglichkeiten, aber ich komm grad nicht drauf 😃

    , CASE WHEN subUser.note > mainUser.note
               THEN subUser.note - mainUser.note
                ELSE mainUser.note - subUser.note END AS diff
    

    mit gruppieren mein ich "GROUP BY" von irgendwelchen Spalten, z.B. wenn du die Summe von irgendwas bilden willst. (Siehe hierzu auch meine erste Antwort).

    Am besten, du probierst erstmal bissl rum 🙂 vielleicht passt es ja scho.



  • subUser.note - mainUser.note AS diff
    

    Bezieht sich das nicht auf zwei Tabellen?
    Letzendich hab ich nur eine und für den query auch nur eine Variable - und zwar MainUserID



  • subUser und mainUser sind lediglich Aliase für ein und die selbe Tabelle.
    Durch ein JOIN auf die gleiche Tabelle macht es sich hier leicht, den Hauptuser mit allen anderen Usern zu vergleichen.



  • Du kannst die Betragsfunktion nutzen:
    http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_abs

    Dann erhältst du nur positive Werte.


Anmelden zum Antworten