MYSQL Abfrage, hier DISTINCT angebracht?
agavensaft
- datenbank
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!!
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ßballIch 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
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
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
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.
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