3 Stimmen

MySQL: Zählen der Anzahl von Elementen innerhalb eines Bereichs

Ich versuche, einige Webprotokolle von meinem Webserver zu analysieren. Ich habe alle Protokolle der letzten Woche in eine Mysql-Datenbank übertragen und analysiere die Protokolle.

Ich habe eine Tabelle erstellt mit sessionID s und die Länge der Sitzung mit diesem mysql-Befehl:

SELECT 
        Log_Analysis_RecordsToSesions.sessionID, 
        ABS(TIMEDIFF(
                MIN(Log_Analysis_Records.date), 
                MAX(Log_Analysis_Records.date)
        )) as session_length
FROM 
        Log_Analysis_RecordsToSesions, 
        Log_Analysis_Records 
WHERE 
        Log_Analysis_RecordsToSesions.recordID=Log_Analysis_Records.recordID 
GROUP BY 
        sessionID;

-

+-----------+----------------+
| sessionID | session_length |
+-----------+----------------+
|         1 |    2031.000000 | 
|         2 |    1954.000000 | 
|         3 |     401.000000 | 
...

Jetzt möchte ich die Anweisung so ändern, dass sie etwa so aussieht:

Range (time)     Number of Sessions
0 to 2           10
2 to 4            4
4 to 6           60
...

Der Bereich wird eine feste Zeitspanne sein, und ich möchte die Anzahl der Sitzungen innerhalb dieses Bereichs zählen. Mein erster Gedanke ist es, Schleife durch sie alle mit php, aber das scheint sehr zeitaufwendig und grob. Gibt es eine Möglichkeit, dies in mysql zu tun?

0voto

greg0ire Punkte 21999

Ich habe Ihren Beitrag bearbeitet und einen Alias hinzugefügt, damit die Ergebnisse besser lesbar sind. Ich denke, Sie könnten so etwas versuchen:

SELECT 
        Log_Analysis_RecordsToSesions.sessionID, 
        ABS(TIMEDIFF(
                MIN(Log_Analysis_Records.date), 
                MAX(Log_Analysis_Records.date)
        )) as session_length,
        CONCAT(session_length DIV 2, ' to ', session_length DIV 2 + 2) as range
FROM 
        Log_Analysis_RecordsToSesions, 
        Log_Analysis_Records 
WHERE 
        Log_Analysis_RecordsToSesions.recordID=Log_Analysis_Records.recordID 
GROUP BY 
         range
ORDER BY session_length;

0voto

Daniel Vassallo Punkte 325264

Vielleicht möchten Sie eine weitere Tabelle erstellen, die Sie ranges :

CREATE TABLE ranges (
   `range` int
);

INSERT INTO ranges VALUES (2), (4), (6), (8);

Dann sollten Sie Ihre Abfrage als abgeleitete Tabelle einpacken und die linke Seite der ranges Tabelle mit der abgeleiteten Tabelle:

SELECT   CONCAT(r.`range` - 2, ' to ', r.`range`) `range`,
         COUNT(session_length) number_of_sessions
FROM     ranges r
LEFT JOIN (
    SELECT    rs.sessionID, 
              ABS(TIMEDIFF(MIN(ar.date), MAX(ar.date))) session_length
    FROM      Log_Analysis_RecordsToSesions rs, 
    JOIN      Log_Analysis_Records ar ON (rs.recordID = ar.recordID )
    GROUP BY  rs.sessionID;
) dt ON (dt.session_length > r.`range` - 2 AND 
         dt.session_length <= r.`range`)
GROUP BY r.`range`;

Für einen Testfall erstellen wir eine Dummy-Tabelle mit einer Reihe von zufälligen Sitzungslängen, wie in Ihrem Beispiel:

CREATE TABLE sessions (
    session_id      int,
    session_length  int
);

INSERT INTO sessions VALUES (1, 2031);
INSERT INTO sessions VALUES (2, 1954);
INSERT INTO sessions VALUES (3, 401);
INSERT INTO sessions VALUES (4, 7505);

Dann können wir Folgendes tun, wobei wir davon ausgehen, dass die ranges Tabelle bereits erstellt wurde:

SELECT   CONCAT(r.`range` - 2, ' to ', r.`range`) `range`,
         COUNT(session_length) number_of_sessions
FROM     ranges r
LEFT JOIN (
    SELECT session_id, session_length FROM sessions
) dt ON (dt.session_length / 1000 > r.`range` - 2 AND 
         dt.session_length / 1000 <= r.`range`)
GROUP BY r.`range`;

Ergebnis:

+--------+--------------------+
| range  | number_of_sessions |
+--------+--------------------+
| 0 to 2 |                  2 |
| 2 to 4 |                  1 |
| 4 to 6 |                  0 |
| 6 to 8 |                  1 |
+--------+--------------------+
4 rows in set (0.00 sec)

0voto

True Soft Punkte 8496

Führen Sie diese Abfrage über Ihre generierte Tabelle aus:

SELECT 
  CONCAT((session_length div 2000)*2, ' to ', ((session_length+2000) div 2000)*2) AS `Range (time)`, 
  COUNT(*) AS `Number of sessions` 
FROM sessions 
GROUP BY session_length div 2000

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X