Nếu tôi hiểu đúng yêu cầu của bạn, nếu biểu đồ này đại diện cho hoạt động của người dùng:
Day
12/1 12/2 12/3 12/4 ...
Hour 0 xx x x xx
1 x xx xx
2 xxx x x xx
3 x x
4 x x
5 x x
6 x
...
Bạn muốn biết rằng 02:00 là thời gian trong ngày có hoạt động trung bình cao nhất (một hàng có 7 x
) và ngày 12/4 là ngày hoạt động tích cực nhất (cột có 10 x
). Lưu ý rằng điều này không có nghĩa là 02:00 ngày 12/4 là giờ hoạt động nhiều nhất từ trước đến nay, như bạn có thể thấy trong ví dụ. Nếu đây không phải là điều bạn muốn, vui lòng làm rõ bằng các ví dụ cụ thể về đầu vào và kết quả mong muốn.
Chúng tôi đưa ra một số giả định:
- Bản ghi hoạt động có thể bắt đầu vào một ngày và kết thúc vào ngày tiếp theo. Ví dụ:trực tuyến
2013-12-02 23:35
, ngoại tuyến2013-12-03 00:13
. - Không có bản ghi hoạt động nào có thời lượng dài hơn 23 giờ hoặc số lượng bản ghi như vậy là không đáng kể.
Và chúng ta cần xác định 'hoạt động' có nghĩa là gì. Tôi đã chọn các tiêu chí dễ tính toán hơn trong từng trường hợp. Cả hai đều có thể được thực hiện chính xác hơn nếu cần, với chi phí là có nhiều truy vấn phức tạp hơn.
- Thời gian hoạt động nhiều nhất trong ngày sẽ là giờ có nhiều bản ghi hoạt động chồng chéo hơn. Xin lưu ý rằng nếu một người dùng bắt đầu và dừng lại nhiều lần trong giờ thì người dùng đó sẽ được tính nhiều hơn một lần.
- Ngày hoạt động tích cực nhất sẽ là ngày có nhiều người dùng duy nhất hoạt động vào bất kỳ thời điểm nào trong ngày.
Đối với thời gian hoạt động nhiều nhất trong ngày, chúng tôi sẽ sử dụng một bảng phụ nhỏ chứa 24 giờ có thể. Nó cũng có thể được tạo và kết hợp nhanh chóng với các kỹ thuật được mô tả trong các câu trả lời khác.
CREATE TABLE hour ( hour tinyint not null, primary key(hour) );
INSERT hour (hour)
VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)
, (11), (12), (13), (14), (15), (16), (17), (18), (19), (20)
, (21), (22), (23);
Sau đó, các truy vấn sau cho kết quả cần thiết:
SELECT hour, count(*) AS activity
FROM steamonlineactivity, hour
WHERE ( hour BETWEEN hour(online) AND hour(offline)
OR hour(online) BETWEEN hour(offline) AND hour
OR hour(offline) BETWEEN hour AND hour(online) )
GROUP BY hour
ORDER BY activity DESC;
SELECT date, count(DISTINCT userID) AS activity
FROM (
SELECT userID, date(online) AS date
FROM steamonlineactivity
UNION
SELECT userID, date(offline) AS date
FROM steamonlineactivity
) AS x
GROUP BY date
ORDER BY activity DESC;