MySQL Abfrage von einer Tabelle

webdoktor

Angesehenes Mitglied
Hallo zusammen

Ich habe eine kleine Frage und zwar habe ich eine Tabelle
mit dem Namen "Friends" welche so aussieht.


id
id_user
id_selbst
status

Nun möchte ich folgendes ich habe z.B. die ID 1 und Mein Kollege die ID 12
Es kann nun sein, dass meine ID bei id_user ist oder bei id_selbst. Nun möchte
ich schauen welche gleiche Freunde ich habe (ID 1) und mein Kollege ID 12.

Die Tabelle sieht z.b. so aus

id - id_user - id_selbst - status
1 - 8 - 1 - 1
2 - 44 - 4 - 1
3 - 1 - 9 - 1
4 - 12 - 5 - 1
5 - 5 - 1 - 1
6 - 77 - 18 - 1
7 - 19 - 12 - 1
8 - 1 - 19 - 1


So wie ihr jetzt da oben sieht, habe ich und mein Kollege folgende gleiche Kollegen:
5 und 19

Genau diese Abfrage möchte ich machen das man sieht, welche gleiche Kollegen wir
haben.

Wisst ihr was ich meine?
Freue mich auf Eure Antworten.

Gruss Marco
 
Warum fügst du nicht alle Freundschaften doppelt ein?
Beispiel (User1, User2):
id_user = 1
id_selbst = 2
id_user = 2
id_selbst = 1
Dann kannst du die Freunde einfacher abfragen und auch deine Frage hier wird leichter:
SELECT id_user FROM freunde WHERE id_selbst IN ('1', '12') GROUP BY id_user HAVING COUNT(*) = 2
 
Hallo cr4m0

Huiii doppelt wäre eigentlich auch eine möglichkeit gewesen. aber ich habe jetzt über
1000 Einträge in dieser Datenbank.

Gibt es auch eine Möglichkeit, wenn es nicht doppelt vorhanden ist.

LG Marco

 
Ich habe keine Idee, wie das gehen könnte. Aber wenn es geht, dann ist es auf jeden Fall sehr kompliziert.

Es müsste ja etwa so gehen:
1) Alle Datensätze holen, bei denen id_user ODER id_selbst den Wert 1 ODER 12 haben.
2) Wenn der Wert in id_user vorkommt, dann ist der Freund in id_selbst, sonst andersrum.
3) Die ID von dem Freund immer in ein Array einfügen.
4) Die doppelten Einträge im Array sind gemeinsame Freunde.

Ich habe aber noch eine Frage an dich: Ich habe das bei meiner Seite so gelöst, dass die Freundschaften doppelt eingetragen werden. Wie machst du das denn, wenn z.B. alle Freund von User "47" gezeigt werden sollen? Machst du dann zwei Abfragen? Also:
1) SELECT ... WHERE id_user = '47'
2) SELECT ... WHERE id_selbst = '47'
Und dann gibtst du die Freunde von beiden Abfragen nacheinander aus!? Oder wie machst du das?
 
Hallo cr4m0

Ich mache einfach eine OR abfrage also so:

SELECT * FROM freunde WHERE id_selbst = '47' OR id_user = '47'

Weisst Du wie ich meine?! Hmm, das mit dem Array habe ich mir auch
schon überlegt. Ist aber wirklich aufwendiger vorallem wenn wir schon
alles schön in einer DB haben sollte das doch irgendwie einfacher gehen?

Schonmal ein Danke an Dich im Voraus für die Bemühungen.

Gruss Marco

 
or ist bezüglich indizies keine gute lösung, besser wäre hier imho auf doppelte einträge nachzurüsten, was ja nicht so schwer ist.
 
QUOTE (Sven K @ Do 7.08.2008, 12:45)or ist bezüglich indizies keine gute lösung, besser wäre hier imho auf doppelte einträge nachzurüsten, was ja nicht so schwer ist.

Datenbanken sind u.a. dafür da, Daten redundanzfrei, also ohne Wiederholungen abzulegen. Also wäre es absurd, deshalb Daten doppelt einzutragen. Union bzw. hier ein Union All leistet dasselbe, dann stehen alle Daten zu einer Person in einer Spalte.

Or verträgt sich problemlos mit Indices.


QUOTE (webdoktor @ Do 7.08.2008, 11:00)So wie ihr jetzt da oben sieht, habe ich und mein Kollege folgende gleiche Kollegen:
5 und 19

Genau diese Abfrage möchte ich machen das man sieht, welche gleiche Kollegen wir
haben.


Was hast Du schon ausprobiert? Wie weit bist Du selbst gekommen?
 
Hallo JAuer

Danke für Deine Antwort. Ich bin auch der Meinung, dass ich die Einträge nicht doppelt eintragen
muss.

Habe leider noch nicht viel probiert da ich keinen Ansatz habe wie ich das machen soll.

Kannst Du mir da helfen?

Gruss Marco

 
Mit UNION müsste das doch so gehen, oder?

SELECT id_user FROM freunde WHERE id_selbst IN ('1', '12')
UNION ALL
SELECT id_selbst FROM freunde WHERE id_user IN ('1', '12')

Dann erhält man alle IDs der gemeinsamen Freunde als "id_user".
 
QUOTE (jAuer @ Do 7.08.2008, 14:30) Datenbanken sind u.a. dafür da, Daten redundanzfrei, also ohne Wiederholungen abzulegen. Also wäre es absurd, deshalb Daten doppelt einzutragen. Union bzw. hier ein Union All leistet dasselbe, dann stehen alle Daten zu einer Person in einer Spalte.

Ohne es jetzt getestet zu haben würde ich behaupten, dass es performanter ist die Einträge doppelt einzufügen, statt per union die Normalisierung durchzusetzen.
 
Hi

Hmm irgendwie stimmt da noch was nicht. Habe folgende Abfrage gemacht:

CODE //Abfragen der Datenbank
$abfrage_freunde_gemeinsam = "SELECT id_user FROM friends_freunde WHERE id_selbst IN ('1', '20')
UNION ALL SELECT id_selbst FROM friends_freunde WHERE id_user IN ('1', '20')";

$ergebnis_freunde_gemeinsam = mysql_query($abfrage_freunde_gemeinsam);
$anzahl_freunde_gemeinsam = mysql_num_rows($ergebnis_freunde_gemeinsam);


Wenn ich dann alles auslese erhalte ich etwa 140 Treffer obwohl diese zwei User nur 2 gleiche Freunde haben.

Was ist da wohl noch falsch?

Marco
 
SELECT id_user FROM freunde WHERE id_selbst IN ('1', '12')
UNION ALL
SELECT id_selbst FROM freunde WHERE id_user IN ('1', '12')
GROUP BY id_user HAVING COUNT(*) = 2

So müsste es gehen. Ich habe die letzte Zeile vergessen.
 
Hi

Danke für Deine Bemühungen.
Komisch es zeigt mir immer noch etwa 50
id's an obwohl es nur etwa 6 gleiche Freunden
sein sollten.

Die Abfrage sieht nun so aus:

CODE $abfrage_freunde_gemeinsam = "SELECT id_user FROM friends_freunde WHERE id_selbst IN ('1', '12')
UNION ALL
SELECT id_selbst FROM friends_freunde WHERE id_user IN ('1', '12')
GROUP BY id_user HAVING COUNT(*) = 2";


Was kann noch falsch sein?

LG Marco
 
QUOTE (webdoktor @ Do 7.08.2008, 13:40)Habe leider noch nicht viel probiert da ich keinen Ansatz habe wie ich das machen soll.

Wie bei allen anderen Problemen auch:

Das Problem in Teilprobleme zerlegen, die Teilprobleme der Reihe nach lösen und dann aus diesen Teillösungen die Gesamtlösung zusammensetzen.

Und die Lösung (bzw. einen wesentlichen Teil davon) habe ich bereits oben gepostet. Genau (!) lesen.

Was macht Union?
Was löst das?
Was bleibt dann offen?
Wie läßt sich das mit Standard-Sql-Befehlen lösen?
Welche Standard-Sql-Befehle gibt es?

Letzteres zu kennen ist natürlich Pflicht und Voraussetzung. Herumraten führt nie zu Lösungen, sondern ist bloße Zeitverschwendung.
 
Man hat das Problem, dass die Freunde in Spalte1 und Spalte2 stehen könne. Das UNION löst das Problem, sodass alle Freunde in einer Spalte stehen.
Man hat dann alle Freunde der beiden Benutzer. Offen bleibt, welche davon gemeinsam sind.
Das könnte man mit "GROUP BY feld HAVING COUNT(*) = 2" lösen.
Irgendwie funktioniert das bei mir aber nicht:

"(SELECT id_user FROM friends_freunde WHERE id_selbst IN ('a', 'b')) UNION ALL (SELECT id_selbst FROM friends_freunde WHERE id_user IN ('a', 'b'))"

Das funktioniert. Jetzt müsste man aus der Menge nur noch die doppelten nehmen.

"(SELECT id_user FROM friends_freunde WHERE id_selbst IN ('a', 'b')) UNION ALL (SELECT id_selbst FROM friends_freunde WHERE id_user IN ('a', 'b')) GROUP BY id_user HAVING COUNT(*) = 2"

Da kommt dann:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY id_user' at line 1
 
QUOTE (cr4m0 @ Fr 8.08.2008, 10:42)Man hat das Problem, dass die Freunde in Spalte1 und Spalte2 stehen könne. Das UNION löst das Problem, sodass alle Freunde in einer Spalte stehen.
Man hat dann alle Freunde der beiden Benutzer. Offen bleibt, welche davon gemeinsam sind.


Im Prinzip nicht schlecht, ich ergänze Kommentare:


QUOTE (cr4m0 @ Fr 8.08.2008, 10:42)Man hat das Problem, dass die Freunde in Spalte1 und Spalte2 stehen könne. Das UNION löst das Problem, sodass alle Freunde {einer Person} in einer Spalte stehen {eine Spalte = Ergebnis einer Unterabfrage}.
Man hat dann alle Freunde der beiden Benutzer {in zwei virtuellen Tabellen}. Offen bleibt, welche davon gemeinsam sind. {Wie findet man die Werte heraus, die gemeinsam in zwei Spalten auftreten? Das ist ein einziger Standard-Sql-Befehl}.

 
Naja, ich verstehe es wohl nicht mehr ...
smile.gif

Ich mache es dann - wie bisher - mit doppelten Einträgen. Das ist doch bestimmt auch von der Performance her besser als UNIONs, virtuelle Tabellen usw.
 
Verstehe ich auch nicht. Das geht doch in einer einfachen Abfrage auch ohne UNION.
Zuerst suchst du alle Spalten mit id-user und id_selbst raus und vergleichst in der where clause die Gegenwerte.

Der einzige Datensatz, der extra-Behandlung bedarf, wäre der Fall, dass du selbst ein Freund deines Kollegen bist.

Den Code kann ich dir leider nicht geben, da love.fincy.com urheberrechtlich geschützt ist.
 
Zurück
Oben