Bạn có thể làm điều này bằng cách sử dụng nhóm với cấp độ mà bạn muốn. Đây là một ví dụ sử dụng dữ liệu bạn đã cung cấp:
Đầu tiên SQL để tạo bảng và điền nó vào. Cột ID ở đây không "cần thiết" nhưng bạn nên dùng nếu bảng lớn hoặc có chỉ mục trên đó.
CREATE TABLE `test`.`events` (
`id` INT NOT NULL AUTO_INCREMENT,
`user` INT NULL,
`start` DATETIME NULL,
`end` DATETIME NULL,
`type` VARCHAR(45) NULL,
PRIMARY KEY (`id`));
INSERT INTO events (user, start, end, type) VALUES
(1, '2015-1-1 12:00:00', '2015-1-1 12:03:59', 'browsing'),
(2, '2015-1-1 12:03:00', '2015-1-1 12:06:00', 'browsing'),
(2, '2015-1-1 12:03:00', '2015-1-1 12:06:00', 'eating'),
(3, '2015-1-1 12:03:00', '2015-1-1 12:08:00', 'browsing');
Để nhận danh sách các cặp có thứ tự từ thời lượng số phút đến số lượng sự kiện:
Sau đó, truy vấn có thể được viết dễ dàng bằng cách sử dụng hàm dấu thời gian, như được hiển thị bên dưới:
SELECT
TIMESTAMPDIFF(MINUTE, start, end) as minutes,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(MINUTE, start, end)
Đầu ra:
minutes numEvents
3 3
5 1
Tham số đầu tiên trong lựa chọn có thể là một trong FRAC_SECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER hoặc YEAR.
Dưới đây là một số ví dụ khác về các truy vấn mà bạn có thể thực hiện:
Sự kiện theo giờ (chức năng tầng được áp dụng)
SELECT
TIMESTAMPDIFF(HOUR, start, end) as hours,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)
** Sự kiện theo giờ với định dạng tốt hơn **
SELECT
CONCAT("<", TIMESTAMPDIFF(HOUR, start, end) + 1) as hours,
COUNT(*) AS numEvents
FROM
test.events
GROUP BY TIMESTAMPDIFF(HOUR, start, end)
Bạn có thể nhóm theo nhiều tùy chọn, nhưng điều này chắc chắn sẽ giúp bạn bắt đầu. Hầu hết các gói biểu đồ sẽ cho phép bạn chỉ định tọa độ x y tùy ý, vì vậy bạn không cần phải lo lắng về việc thiếu các giá trị trên trục x.
Để nhận danh sách các cặp số sự kiện được sắp xếp theo thứ tự tại một thời điểm cụ thể (để ghi nhật ký): Lưu ý rằng điều này được để lại để tham khảo.
Bây giờ cho các truy vấn. Đầu tiên, bạn phải chọn mục bạn muốn sử dụng để phân nhóm. Ví dụ:một nhiệm vụ có thể mất hơn một phút, vì vậy thời gian bắt đầu và kết thúc sẽ diễn ra trong các phút khác nhau. Đối với tất cả các ví dụ này, tôi căn cứ vào thời gian bắt đầu, vì đó là thời điểm sự kiện thực sự diễn ra.
Để nhóm các số lượng sự kiện theo phút, bạn có thể sử dụng truy vấn như sau:
SELECT
DATE_FORMAT(start, '%M %e, %Y %h:%i %p') as minute,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start), DAYOFMONTH(start), HOUR(start), MINUTE(start);
Lưu ý cách nhóm này theo tất cả các mục, bắt đầu bằng năm, theo phút. Tôi cũng có phút hiển thị dưới dạng nhãn. Kết quả đầu ra trông giống như sau:
minute numEvents
January 1, 2015 12:00 PM 1
January 1, 2015 12:03 PM 3
Đây là dữ liệu mà sau đó bạn có thể lấy bằng php và chuẩn bị cho nó hiển thị bởi một trong nhiều thư viện vẽ đồ thị ngoài đó, vẽ cột phút trên trục x và vẽ biểu đồ numEvents trên trục y.
Dưới đây là một số ví dụ khác về các truy vấn mà bạn có thể thực hiện:
Sự kiện theo giờ
SELECT
DATE_FORMAT(start, '%M %e, %Y %h %p') as hour,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start), DAYOFMONTH(start), HOUR(start);
Sự kiện theo ngày
SELECT
DATE_FORMAT(start, '%M %e, %Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start), DAYOFMONTH(start);
Sự kiện theo tháng
SELECT
DATE_FORMAT(start, '%M %Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start), MONTH(start);
Sự kiện theo năm
SELECT
DATE_FORMAT(start, '%Y') as date,
count(*) AS numEvents
FROM test.events
GROUP BY YEAR(start);
Tôi cũng nên chỉ ra rằng nếu bạn có chỉ mục trên cột bắt đầu cho bảng này, các truy vấn này sẽ hoàn thành nhanh chóng, ngay cả với hàng trăm triệu hàng.
Hi vọng điêu nay co ich! Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi nào khác về vấn đề này.