php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Entwicklung > SQL / Datenbanken
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

 

 


SQL / Datenbanken Probleme mit SQL? Hier könnt ihr eure Fragen zu SQL (MySQL, PostgreSQL, MS-SQL und andere ANSI-SQL Server) los werden.

Antwort
 
LinkBack Themen-Optionen Thema bewerten
  #1 (permalink)  
Alt 07-01-2011, 17:46
skalu
 Member
Links : Onlinestatus : skalu ist offline
Registriert seit: May 2003
Ort: Wien
Beiträge: 362
skalu ist zur Zeit noch ein unbeschriebenes Blatt
skalu eine Nachricht über ICQ schicken
Standard GROUP BY Problem

Hi Leute,

ich habe folgendes Problem: in einer Tabelle "activities" speichere ich für jeden angemeldeten Benutzer seine Session + User-ID + letzte Aktivität. Nun möchte ich mir eine Liste ausgeben lassen, wer gerade aktiv ist. Das Problem ist nur, dass wenn sich ein User einloggt, dann seine Session nicht per Logout sondern über Schließen des Browserfensters beendet und sich dann binnen einiger Minuten nochmal einloggt, wird er von meinem Script so gesehen, als wäre er 2x eingeloggt, weil beide "letzte Aktivitäten" innerhalb des von mir festgelegten Timeouts von 10 Minuten liegen.

Gebe ich mir nun alle Aktivitäten der letzten 10 Minuten aus, erhalten ich den Benutzer, der sich 2x hintereinander eingeloggt hat, 2x angezeigt. Nun zum Problem: dem möchte ich per GROUP BY user_id entgegen wirken, jedoch erhalte ich dann immer den ältesten Datensatz und nicht den aktuellsten. Eine Kombination mit ORDER BY last_activity ändert an diesem Problem nichts.

Wie kann ich GROUP BY so einsetzen, dass ich jeden Benutzer nur 1x angezeigt bekomme und dann nur den neusten Datensatz?

Struktur + Beispieleinträge
activity_id | user_id | session_id | last_activity
---------------------------------------------
1 | 1 | id1 | timestamp1 (id1 und timestamp sind hier nur angedeutet)
2 | 5 | id2 | timestamp2
3 | 7 | id3 | timestamp3
4 | 5 | id4 | timestamp4 (neuester Eintrag)

>> group ich nun by user_id, erhalte ich als letzte Aktivität des Users "5" timestamp2 und nicht den neueren timestamp4. Hoffe ich konnte das gut erklären...

Danke, Skalu
Mit Zitat antworten
  #2 (permalink)  
Alt 07-01-2011, 18:32
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Hallo,

du musst natürlich

Code:
ORDER BY last_activity DESC
angeben.

Gruß,

Amica
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
Mit Zitat antworten
  #3 (permalink)  
Alt 07-01-2011, 18:38
skalu
 Member
Links : Onlinestatus : skalu ist offline
Registriert seit: May 2003
Ort: Wien
Beiträge: 362
skalu ist zur Zeit noch ein unbeschriebenes Blatt
skalu eine Nachricht über ICQ schicken
Standard

Hi Amica,

ich habe in meinem 1. Beitrag vergessen, das DESC hinzuschreiben, aber die ORDER BY Klausel habe ich schon genauso probiert, wie du. Bringt leider nichts

Skalu
Mit Zitat antworten
  #4 (permalink)  
Alt 07-01-2011, 18:49
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Hm, dann bleibt dir immer noch der negative self left join. Siehe hier: Eine kleine, harte Nuss
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
Mit Zitat antworten
  #5 (permalink)  
Alt 07-01-2011, 22:51
skalu
 Member
Links : Onlinestatus : skalu ist offline
Registriert seit: May 2003
Ort: Wien
Beiträge: 362
skalu ist zur Zeit noch ein unbeschriebenes Blatt
skalu eine Nachricht über ICQ schicken
Standard

Hi Amica,

danke für deine Antwort! Die Idee mit dem JOIN klingt ja sehr gut Ich habe mir deinen Link angesehen und mein Query mal so umgebaut, wie in deinem Beispiel. Leider verstehe ich einen Teil nicht bzw. denke ich, dass ich etwas falsch mache, weil das Query noch nicht so funktioniert, wie ich es brauche (ich bekomme nun ungefiltert alle Einträge, als ob ich kein GROUP BY verwenden würde.

Code:
SELECT * FROM user_activities t1 LEFT JOIN user_activities t2 
ON t1.activity_id = t2.activity_id AND t2.last_activity < t1.last_activity
WHERE t1.last_activity > '$timeout_ts'
ORDER BY t1.activity_id DESC
$timeout_ts ist der aktuelle TS minus meinem Timeout (- 10 min).

Kannst du mir vielleicht kurz erklären, was ich bei dem negativen JOIN theoretisch machen muss? Der Teil "AND t2.last_activity < t1.last_activity" scheint der Teil zu sein, der die Daten so selektiert, dass die neueren Datensätze gewählt werden.

Danke dir für deine Hilfe!

Skalu
Mit Zitat antworten
  #6 (permalink)  
Alt 07-01-2011, 23:06
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Im ON-Teil musst du den Vergleich umkehren (also t2.last_activity > t1.last_activity) und dann fehlt in der Where-Klausel noch das
Code:
AND t2.activity_id IS NULL
Das GROUP BY dagegen fliegt raus.

Die umgekehrte Bedingung bei ON und das IS NULL in der Where-Klausel machen das negative am negativen join aus.
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
Mit Zitat antworten
  #7 (permalink)  
Alt 08-01-2011, 11:07
skalu
 Member
Links : Onlinestatus : skalu ist offline
Registriert seit: May 2003
Ort: Wien
Beiträge: 362
skalu ist zur Zeit noch ein unbeschriebenes Blatt
skalu eine Nachricht über ICQ schicken
Standard

Hi Amica,

tut mir Leid, dass sich das so zieht, aber es funktioniert leider noch immer nicht Hier mal das Query, das ich mir im Script habe ausgeben lassen:

Code:
SELECT * FROM user_activities t1 LEFT JOIN user_activities t2 
ON t1.activity_id = t2.activity_id AND t2.last_activity > t1.last_activity 
WHERE t1.last_activity >=1294480114 AND t1.activity_logged_out = 0 
AND t2.activity_id IS NULL ORDER BY t1.activity_id DESC
activity_logged_out ist bei allen Einträgen 0, spielt also keine Rolle und auch ohne diese Bedingung funktioniert es nicht. Leider bekomme ich noch immer Benutzer 2x angezeigt...

Kann da noch etwas falsch sein/fehlen?

Wenn ich das Query direkt in PHPMyAdmin eingebe, bekomme ich für alle Felder von t2 den Wert NULL. In der WHERE Bedingung frage ich das ja ab - ist das so in Ordnung, dass alle Felder von t2 den Wert NULL haben? Ich schreibe das nur, falls das eine Fehlerquelle sein könnte...

Danke vielmals für deine Bemühungen!

Skalu
Mit Zitat antworten
  #8 (permalink)  
Alt 08-01-2011, 11:13
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Ich kenne deine DB leider nicht, daher kann ich nicht viel dazu sagen.

Folgender Vorschlag: Poste das Ergebnis der Abfrage ohne die Where-Klausel (mind. 20 Datensätze):

Code:
SELECT *
FROM user_activities AS t1
LEFT JOIN user_activities AS t2 
    ON t1.activity_id = t2.activity_id AND t2.last_activity > t1.last_activity 
ORDER BY t1.activity_id DESC
Schreib dann dazu, welche Datensätze du nicht haben willst und warum.
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
Mit Zitat antworten
  #9 (permalink)  
Alt 08-01-2011, 11:55
skalu
 Member
Links : Onlinestatus : skalu ist offline
Registriert seit: May 2003
Ort: Wien
Beiträge: 362
skalu ist zur Zeit noch ein unbeschriebenes Blatt
skalu eine Nachricht über ICQ schicken
Standard

Hi Amica,

danke für deine Mühe - los geht's

Also wenn ich keine WHERE Bedingung habe, erhalte ich ein solches Ergebnis ("[session_id]" enthält die jeweilige SESSION-iD (z.B. 4jal32k3jaskdj usw)):

activity_id | activity_user | activity_session_id | last_activity | ...
----------------------------------------------------------------
1 | 1 | [session_id ] | [alter Timestamp]
2 | 4 | [session_id ] | [neuerer Timestamp]
3 | 6 | [session_id ] | [noch neuerer Timestamp]
4 | 4 | [session_id ] | [noch neuerer Timestamp] <-- dieser Timestamp liegt beispielsweise nicht in den letzten 10 Min -> ist also schon uninteressant
5 | 1 | [session_id ] | [noch neuerer Timestamp] <-- dieser Timestamp von Benutzer "1" ist älter, als jener von Benutzer "1" ganz unten (Acitivity-ID 8) - diesen will ich somit nicht berücksichtigen, obwohl er in die letzten 10 Minuten fällt
6 | 7 | [session_id ] | [noch neuerer Timestamp] <-- will ich berücksichtigen, weil der neueste von Benutzer "7"
7 | 4 | [session_id ] | [noch neuerer Timestamp] <-- will ich auch berücksichtigen, weil neuester von Benutzer "4"
8 | 1 | [session_id ] | [neuester Timestamp] <-- diesen Eintrag von Benutzer "1" will ich schon berücksichtigen, weil er ist der neueste von Benutzer "1"

Sind jetzt nur 8 Ergebnisse - denke das reicht auch, um das Problem zu erklären: 8 User haben sich insgesamt eingeloggt.
- Die ersten 4 Einträge hatten ihre letzte Aktivität vor über 10 Minuten -> uninteressant, weil schon zu alt.
- Der Eintrag 5 ist zwar von Benutzer 1, es gibt aber noch neuere, deswegen auch uninteressant.
- Eintrag 6 von Benutzer 7 ist der einzige von Benutzer 7 -> es gibt keinen neueren -> will ich berücksichtigen
- Eintrag 7 ist der 3. von Benutzer 4, aber der neueste (die beiden älteren sind also uninteressant)
- Eintrag 8 ist der neueste von Benutzer 1 -> somit will ich nur diesen von Benutzer 1 anzeigen.

Es geht also darum, von jedem Benutzer immer nur den neuesten Eintrag anhand von "activity_timestamp" zu ermitteln, aber jeden Benutzer immer nur 1x anzuzeigen und dann nur den neuesten Eintrag in der Tabelle. Ich bekomme im Ergebnis also 4 Einträge, die in die letzten 10 Minuten fallen (Einträge 5-8 = fett markiert). In diesen 4 kommt aber ein Benutzer 2x vor (weil er sich nicht ausgeloggt, sondern nur sein Fenster geschlossen hat und sich ein 2. Mal eingeloggt hat, dennoch innerhalb von 10 Minuten). Diesen Benutzer will ich aber nur 1x angezeigt bekommen und zwar nur dessen neuesten Eintrag = neueste Aktivität. Der 2. (ältere) Eintrag dieses Benutzers ist nicht mehr relevant.

Hoffe ich konnte das nun besser erklären!

Danke, Skalu
Mit Zitat antworten
  #10 (permalink)  
Alt 08-01-2011, 13:00
AmicaNoctis
  Moderatorin
Links : Onlinestatus : AmicaNoctis ist offline
Registriert seit: Jul 2009
Beiträge: 5.709
Blog-Einträge: 9
AmicaNoctis sorgt für eine eindrucksvolle AtmosphäreAmicaNoctis sorgt für eine eindrucksvolle Atmosphäre
Standard

Achsoooo, dann nimm nochmal die Abfrage von hier und ersetze in der ON-Klausel activity_id durch activity_user.
__________________
Hast du die Grundlagen zur Fehlersuche gelesen? Hast du Code-Tags benutzt?
Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
Super, danke!
Mit Zitat antworten
  #11 (permalink)  
Alt 08-01-2011, 23:08
skalu
 Member
Links : Onlinestatus : skalu ist offline
Registriert seit: May 2003
Ort: Wien
Beiträge: 362
skalu ist zur Zeit noch ein unbeschriebenes Blatt
skalu eine Nachricht über ICQ schicken
Standard

Amica, du bist ein Genie Vielen Dank - jetzt funktioniert es endlich so, wie ich's wollte!! Danke für deine Geduld!!!

Skalu
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
GROUP BY Problem Greaseball SQL / Datenbanken 8 03-02-2007 20:11
order by group by problem zimmbi SQL / Datenbanken 4 27-11-2005 18:33
GROUP BY problem php_rookie SQL / Datenbanken 3 09-09-2004 18:03
GROUP BY - Problem Nolabel SQL / Datenbanken 7 13-07-2004 15:46
problem mit group by Thommy SQL / Datenbanken 2 18-01-2002 15:27

Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an


PHP News

ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlicht
ebiz-trader 7.5.0 mit PHP7 Unterstützung veröffentlichtDie bekannte Marktplatzsoftware ebiz-trader ist in der Version 7.5.0 veröffentlicht worden.

28.05.2018 | Berni

Wissensbestand in Unternehmen
Wissensbestand in UnternehmenLebenslanges Lernen und Weiterbilden sichert Wissensbestand in Unternehmen

25.05.2018 | Berni


 

Aktuelle PHP Scripte

PHP Server Monitor

PHP Server Monitor ist ein Skript, das prüft, ob Ihre Websites und Server betriebsbereit sind.

11.09.2018 Berni | Kategorie: PHP/ Security
PHP WEB STATISTIK ansehen PHP WEB STATISTIK

Die PHP Web Statistik bietet Ihnen ein einfach zu konfigurierendes Script zur Aufzeichnung und grafischen und textuellen Auswertung der Besuchern Ihrer Webseite. Folgende zeitlichen Module sind verfügbar: Jahr, Monat, Tag, Wochentag, Stunde Folgende son

28.08.2018 phpwebstat | Kategorie: PHP/ Counter
Affilinator - Affilinet XML Produktlisten Skript

Die Affilinator Affilinet XML Edition ist ein vollautomatisches Skript zum einlesen und darstellen der Affili.net (Partnerprogramm Netzwerk) Produktlisten und Produktdaten. Im Grunde gibt der Webmaster seine Affilinet PartnerID ein und hat dann unmittelb

27.08.2018 freefrank@ | Kategorie: PHP/ Partnerprogramme
 Alle PHP Scripte anzeigen

Alle Zeitangaben in WEZ +2. Es ist jetzt 10:32 Uhr.