Vinzenz Mai: Rückgabewerte sind geordnet? lässt sich das verhindern?

Beitrag lesen

Hallo Martin       <= nicht nur ich sehe hier gerne eine Anrede

Ok, ich versuche es noch genauer anhand von Beispielen.
Stell Dir sowas wie ne Hobbysuchseite vor. Da tragen sich Leute ein und geben ihre Interessen an.
Nun kannst Du angeben was Du suchst und bekommst die Leute angezeigt, die am meisten mit Dir gemein haben. Das ist sehr vereinfacht, reicht aber.

Was in der Datenbank steht:
Eine Tabelle mit persönlichen Daten der Nutzer. Nennen wir sie "personen"
Eine Tabelle mit einer Angabe der Hobbies. Diese besteht aus einer ID, einem "Hobby" und einer ReferenzID zu den Daten in "personen". Nennen wir diese Tabelle "hobby"

So sieht "hobby" etwa aus:

id   hobby        personID

1    busfahren    1001
2    schlafen     1002
3    schlafen     1001
4    staubsaugen  1003
5    nachdenken   1002
6    nachdenken   1003
7    schlafen     1003
[..]

Tabelle "person" oder so ähnlich sieht wohl in etwa so aus

personID    vorname     name
1001        Otto        Normalverbraucher
1002        Tante       Emma
1003        Martin      Unbekannt

Über die mehrfachen Einträge der Hobbys (sieht grausam aus, diese neue Rechtschreibung) sag' ich mal nichts.

Nun kann ich als Besucher der Seite suchen, etwa nach "schlafen und  busfahren". Dabei ist nicht zwingend eine totale übereinstimmung erforderlich, sondern nur eine bestmögliche.

mein SQL Query liefert mir dann "1001,1002,1001,1003". Nach der Umformung über array_count_values und einer Sortierung habe ich dann das schöne Ergebnis: "1001,1003,1002"

Früh, vielleicht zu früh, verläßt Du hier den SQL-Bereich

"1001" hat die meisten Übereinstimmungen und kommt deshalb ganz vorne und 1003 kommt vor 1002 weil die ID höher ist und das heisst der Nutzer ist neuer in der Datenbank und sollte deshalb auch eher angezeigt werden.
Naja soweit so gut, funktioniert ja alles.

Warum hörst Du hier bereits mit SQL auf, bemühst eine externe Programmiersprache? Lass Doch SQL etwas mehr tun. Es geht.

1. Schritt: Details reinbringen

  
SELECT  
   p.vorname,  
   p.name,  
   h.personID  
FROM person AS p  
INNER JOIN hobby AS h  
ON p.personID = h.personID  

2. Schritt: Einträge der Personen zählen

  
SELECT  
   p.vorname,  
   p.name,  
   p.personID,  
   COUNT(h.personID) AS anzahl  
FROM person AS p  
INNER JOIN hobby AS h  
ON p.personID = h.personID  
GROUP BY p.vorname, p.name, p.personID  

Da mit COUNT eine Aggregatsfunktion ins Spiel kommt, müssen
alle anderen aufgeführten Spalten in die GROUP BY-Klausel
kommen, da für diese keine Aggregatsfunktion verwendet wird.
(Ok, MySQL ist da großzügig - ich nicht)

3. Schritt: Halt, nur die mit den gewünschten Hobbys!
Da nach den Hobbys nicht gruppiert wird, wird die WHERE-Klausel
verwendet. Die WHERE-Klausel kommt im SELECT-Statement vor
GROUP BY

  
SELECT  
   p.vorname,  
   p.name,  
   p.personID,  
   COUNT(h.personID) AS anzahl  
FROM person AS p  
INNER JOIN hobby AS h  
ON p.personID = h.personID  
WHERE h.hobby IN ('schlafen', 'nachdenken')  
GROUP BY p.vorname, p.name, p.personID  

4. Schritt: Ja, aber ich will die meisten Übereinstimmungen oben
ORDER BY mit DESC

  
SELECT  
   p.vorname,  
   p.name,  
   p.personID,  
   COUNT(h.personID) AS anzahl  
FROM person AS p  
INNER JOIN hobby AS h  
ON p.personID = h.personID  
WHERE h.hobby IN ('schlafen', 'nachdenken')  
GROUP BY p.vorname, p.name, p.personID  
ORDER BY anzahl DESC  

5. Schritt: Das reicht noch nicht, bei Gleichheit entscheidet
   die höhere id

  
SELECT  
   p.vorname,  
   p.name,  
   p.personID,  
   COUNT(h.personID) AS anzahl  
FROM person AS p  
INNER JOIN hobby AS h  
ON p.personID = h.personID  
WHERE h.hobby IN ('schlafen', 'nachdenken')  
GROUP BY p.vorname, p.name, p.personID  
ORDER BY anzahl DESC, h.personID DESC  

Sollte das gewünschte Ergebnis liefern. Mein Code ist getestet, Fehler aus meinem vorherigen Posting sind eliminiert :-)).

Ich weiß, dass es nicht unbedingt didaktisch klug ist, eine Komplettlösung abzuliefern, das war auch nicht meine Intention. Ich möchte Dir hier im Ansatz zeigen, was mit SQL möglich ist. Ich möchte Dich motivieren, Dich intensiver mit SQL (und auch PHP) zu befassen. Lerne, mit dem Handbuch umzugehen. Lerne, Tutorials sinnvoll zu benutzen. Das hier ist sozusagen ein Minitutorial.

Ganz besonders möchte ich Dir zeigen, dass es sinnvoll sein kann, das Gesamtproblem zu schildern. Vielleicht kommst Du so zu einem neuen Lösungsansatz, der Dir derzeit existierende Probleme aus dem Weg räumt, weil sie dann gar nicht mehr auftreten. Ich freue mich darauf, wieder von Dir zu lesen.

Ich werde mir jetzt ein Bier aufmachen

Prost!

und das Notebook beleidigen, sowas hat in der jüngeren Vergangenheit beim Denken geholfen.

Wenn das Notebook beleidigt ist und Dir nicht mehr so recht gehorchen will, darfst Du es gern mir schenken. Ich werde es fachgerecht entsorgen.

Freundliche Grüße

Vinzenz