agavensaft: MYSQL Abfrage, hier DISTINCT angebracht?

Ich komme bei einer MYSQL Abfrage einfach nicht weiter und würde mich riesig freuen von euch einen Denkanstoß zu bekommen.

Ich habe zwei Tabellen:

Tabelle1:
Ausgabe abhängig von der userid:
Spanien, Reisen, Programmieren

Tabelle2:
VON TAG
1 Spanien
1 Reisen
1 Programmieren
38 Klatschen
24 Fußball

Ich würde gerne aus Tabelle2 alle Datensätze erhalten, wo so viele Datensätze wie möglich aus Tabelle1 vorkommen, die auch den identischen VON-Wert besitzen...

also im Idealfall soll herauskommen

VON 1 hat 3 TAGS, die DIR gefallen

ich würde es irgendwie mit SELECT DISTINCT VON WHERE TAG LIKE='%usertag%' versuchen, wie gefällt das?

bin über jeden Hinweis äußerst Dankbar, schönen Samstag!!

  1. Hallo

    Ich komme bei einer MYSQL Abfrage einfach nicht weiter und würde mich riesig freuen von euch einen Denkanstoß zu bekommen.

    Ich habe zwei Tabellen:

    Tabelle1:
    Ausgabe abhängig von der userid:
    Spanien, Reisen, Programmieren

    Das ist Unsinn! Was steht in Tabelle 1.  Der Inhalt ist doch sicherlich unabhängig von irgendeiner userid.

    Welche Spalten gibt es, welche Werte.
    Wenn in Tabelle 1 in irgendeiner Spalte irgendetwas wie "Spanien", "Reisen", "Programmieren" steht, dann solltest Du Dir Dein Tabellendesign überlegen.

    Tabelle2:
    VON TAG
    1 Spanien
    1 Reisen
    1 Programmieren
    38 Klatschen
    24 Fußball

    Ich würde gerne aus Tabelle2 alle Datensätze erhalten, wo so viele Datensätze wie möglich aus Tabelle1 vorkommen, die auch den identischen VON-Wert besitzen...

    also im Idealfall soll herauskommen

    VON 1 hat 3 TAGS, die DIR gefallen

    ich würde es irgendwie mit SELECT DISTINCT VON WHERE TAG LIKE='%usertag%' versuchen, wie gefällt das?

    Abwegig. Mit einem Join, ggf. einem Subselect und Aggregatsfunktionen sollte
    Dein Problem zu bewältigen sein. Ohne weitere Informationen kann man Dir kaum
    weiterhelfen.

    Bitte gib noch Deine MySQL-Version an.

    Freundliche Grüße

    Vinzenz

    1. Hi Vinzenz, danke für die schnelle Antwort.

      Das ist Unsinn! Was steht in Tabelle 1.  Der Inhalt ist doch sicherlich unabhängig von irgendeiner userid.

      Welche Spalten gibt es, welche Werte.
      Wenn in Tabelle 1 in irgendeiner Spalte irgendetwas wie "Spanien", "Reisen", "Programmieren" steht, dann solltest Du Dir Dein Tabellendesign überlegen.

      In Tabelle1 stehen die userTAGS, die werden ausgegeben nach userID.

      Sagen wir die Spalten heißen WER, DATUM, WAS

      und WAS wird in einer while-Abfrage ausgegeben in Abhängigkeit von WER, daher z.B. die drei TAGS Spanien, Reisen, Programmieren

      Abwegig. Mit einem Join, ggf. einem Subselect und Aggregatsfunktionen sollte
      Dein Problem zu bewältigen sein. Ohne weitere Informationen kann man Dir kaum
      weiterhelfen.

      Bitte gib noch Deine MySQL-Version an.

      MySQL Version:  3.23.58

      Die Abfrage muss also in der zweiten Tabelle nachgucken, ob es jeweils zu den einzelnen userTAGS gleiche vonIDs gibt (dies ist der Fall)
      Für mich wäre es logisch folgendermaßen vorzugehen:

      Jeweils schauen ob der jeweilige userTAG in tabelle2 vorkommt, ihn in ein zweidimensionales array speichern mit id und name
      und dann untersuchen, ob es arrays gibt, die einen unterschiedlichen TAGnamen haben, aber die gleiche ID vorweisen
      wenn dies der fall ist, würde ich das Ergebnis nach Häufigkeitsübereinstimmung sortieren (Drei Tags mit gleicher ID sind besser als z.B. zwei) und dann hätte ich ein perfektes ergebnis

      Bevor ich mich da ran mache, wollte ich mich nur versichern, dass es keine saubere Lösung evtl. gleich mit MySQL gibt.

      Mit freundlichen Grüßen
      agavensaft

      1. Hallo

        In Tabelle1 stehen die userTAGS, die werden ausgegeben nach userID.

        Sagen wir die Spalten heißen WER, DATUM, WAS

        und WAS wird in einer while-Abfrage ausgegeben in Abhängigkeit von WER, daher z.B. die drei TAGS Spanien, Reisen, Programmieren

        Argh. Sowas macht man nicht. Du willst offensichtlich Joins mit irgendeiner
        dämlichen Programmiersprache nachbauen.

        Bitte poste Beispielinhalt _genau_ dieser Tabelle, wie ich schon schrieb.

        Abwegig. Mit einem Join, ggf. einem Subselect und Aggregatsfunktionen sollte
        Dein Problem zu bewältigen sein. Ohne weitere Informationen kann man Dir kaum
        weiterhelfen.

        Bitte gib noch Deine MySQL-Version an.
        MySQL Version:  3.23.58

        OK, Subselects fallen somit flach. Die gibt es erst ab 4.1.x.

        Jeweils schauen ob der jeweilige userTAG in tabelle2 vorkommt, ihn in ein zweidimensionales array speichern mit id und name
        und dann untersuchen, ob es arrays gibt, die einen unterschiedlichen TAGnamen haben, aber die gleiche ID vorweisen

        Ja, ja. Baue einen Join mittels API nach. Klingt unsinnig und unperformant.

        Bevor ich mich da ran mache, wollte ich mich nur versichern, dass es keine saubere Lösung evtl. gleich mit MySQL gibt.

        Ja, selbstverständlich sollte es das geben. Bei Deiner Version sieht es allerdings danach aus, als müsste man den unsauberen MAX_CONCAT-Trick anwenden.

        Du solltest an einen Providerwechsel denken. MySQL 3.23.58 ist eine Museumsversion. Siehe dazu http://dev.mysql.com/doc/refman/4.1/en/index.html, für diese Version
        gibt es noch nicht einmal mehr Sicherheitsupdates.

        Freundliche Grüße

        Vinzenz

        1. Danke für die Antwort,

          Bitte poste Beispielinhalt _genau_ dieser Tabelle, wie ich schon schrieb.

          tabelle z_usertags

          WER    DATUM    WAS
          --------------------
           1     XXXXXX   Spanien
           1     XXXXXX   Reisen
           2     XXXXXX   New York
           1     XXXXXX   Programmieren

          Danke für deinen Tipp - habe jetzt die Version 4.1.22 raufgespielt. Hoffe jetzt ist einiges mehr im Bereich des Möglich.

          1. Hallo

            Bitte poste Beispielinhalt _genau_ dieser Tabelle, wie ich schon schrieb.

            Hmm, zu wenig Daten. Ich ergänze ein paar Datensätze, damit die Abfrage sinnvoll wird. Dabei hoffe ich, die Logik Deiner Tabellen richtig verstanden
            zu haben

            tabelle z_usertags

            WER    DATUM    WAS

            1     XXXXXX   Spanien
            1     XXXXXX   Reisen
            2     XXXXXX   New York
            1     XXXXXX   Programmieren

            3     XXXXXX   Fußball
               3     XXXXXX   Klatschen

            Tabelle2:
            VON TAG
            1    Spanien
            1    Reisen
            1    Programmieren
            38   Klatschen
            24   Fußball
            17   Reisen
            17   Programmieren
            17   Fußball
            17   Klatschen
            19   New York

            Ich gehe nun davon aus, dass Du folgendes Resultat haben willst:

            Wer Von Anzahl
            --------------
              1   1   3
              2  19   1
              3  17   2

            Danke für deinen Tipp - habe jetzt die Version 4.1.22 raufgespielt. Hoffe jetzt ist einiges mehr im Bereich des Möglich.

            Ja, die kann Subselects.

            Wie kommst Du nun ans Ziel?
            Ich bin heute nicht fit, meine Lösung sieht mir zu kompliziert aus :-(
            Sie hat einen Vorteil: Sie funktioniert.

            Nun Schritt für Schritt:

            Schritt 1:
            Wir schauen uns an, wer was von wem getaggt hat:

            SELECT  
                t1.wer,  
                t2.von  
            FROM  
                z_usertags t1    -- Ich benutze hier Tabellenaliasnamen aus Faulheit  
            INNER JOIN  
                tabelle2 t2  
            ON  
                t1.was = t2.tag
            

            liefert:

            wer         von
            ----------- -----------
            1           1
            1           1
            1           17
            2           19
            1           1
            1           17
            3           24
            3           17
            3           38
            3           17

            (10 Zeile(n) betroffen)

            Schritt 2: Wir zählen, wer wie oft die Begriffe einer Person getaggt hat:

            SELECT  
                t1.wer,               -- um wessen Tags geht es  
                t2.von,               -- wer hat diese getaggt  
                COUNT(t2.von) Anzahl  -- wie viele hat er getaggt  
            FROM  
                z_usertags t1  
            INNER JOIN  
                tabelle2 t2  
            ON  
                t1.was = t2.tag  
            GROUP BY                  -- gruppiert  
                t1.wer,               -- nach der Person  
                t2.von
            ~~~         -- und denjenigen, die dessen Begriffe taggen  
              
            liefert als Ergebnis:  
              
            wer         von         Anzahl  
            \----------- ----------- -----------  
            1           1           3  
            1           17          2  
            3           17          2  
            2           19          1  
            3           24          1  
            3           38          1  
              
            Nun bist Du nur an denjenigen je Person (wer) interessiert, die am häufigsten  
            getaggt haben:  
              
            Wäre dies die Ausgangstabelle, so liefert Dir eine korrelierte Unterabfrage  
              
            ~~~sql
            SELECT                         -- Gib mir  
                t3.wer,                    -- die Personen  
                t3.von,                    -- und diejenigen, die getaggt haben  
                t3.Anzahl                  -- und die Anzahl  
            FROM tabelle t3  
            WHERE                          -- aber nur die,  
                t3.Anzahl = (  
                    SELECT  
                        MAX(t4.Anzahl)     -- die die meisten Tags zu  
                    FROM tabelle t4  
                    WHERE t3.wer = t4.wer  -- einer bestimmten Person vorgenommen haben  
                    GROUP BY t4.wer  
            ) 
            

            die gewünschten Datensätze:

            wer         von         Anzahl
            ----------- ----------- -----------
            1           1           3
            3           17          2
            2           19          1

            Schritt 4:
            Statt Tabelle 3 müssen wir das SELECT-Statement aus Schritt 2 nehmen - und zwar außen wie innen:

            SELECT  
                t4.wer,  
                t4.von,  
                t4.Anzahl  
            FROM (  
                SELECT  
                    t1.wer,  
                    t2.von,  
                    COUNT(t2.von) Anzahl  
                FROM  
                    z_usertags t1  
                INNER JOIN  
                    tabelle2 t2  
                ON  
                    t1.was = t2.tag  
                GROUP BY  
                    t1.wer,  
                    t2.von  
            ) t4                     -- Beachte, dass Du der Subquery einen Namen geben musst!  
            WHERE  
                t4.Anzahl = (  
                    SELECT  
                        MAX(t5.Anzahl)  
                    FROM (  
                        SELECT  
                            t1.wer,  
                            t2.von,  
                            COUNT(t2.von) Anzahl  
                        FROM  
                            z_usertags t1  
                        INNER JOIN  
                            tabelle2 t2  
                        ON  
                            t1.was = t2.tag  
                        GROUP BY  
                            t1.wer,  
                            t2.von  
                    ) t5             -- Auch hier ist die Namensgebung zwingend notwendig.  
                    WHERE t4.wer = t5.wer  
                    GROUP BY t5.wer  
                )  
            
            

            liefert ebenfalls das gewünschte Resultat:

            wer         von         Anzahl
            ----------- ----------- -----------
            1           1           3
            2           19          1
            3           17          2

            (3 Zeile(n) betroffen)

            Anmerkungen:
            1. Du kannst natürlich nach jeder beliebigen Spalte sortieren.
            2. Ich hoffe nur, dass ich Deine Problemstellung richtig verstanden habe.

            Freundliche Grüße

            Vinzenz