Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

mysql chọn số hàng giữa khoảng thời gian

Được rồi, tôi nhận ra mình hơi muộn, nhưng dù sao thì tôi cũng muốn đăng câu trả lời của mình :-)

Những gì bạn yêu cầu có thể được thực hiện bằng cách sử dụng truy vấn con, nhưng điều này có thể mất nhiều thời gian để hoàn thành trên một bảng lớn ...

Suy nghĩ về câu hỏi, tôi đi đến hai cách tiếp cận khác nhau.

Một trong số chúng đã được xử lý trong các câu trả lời khác, nó hoạt động bằng cách bắt đầu tại một thời điểm cụ thể, xem xét khoảng thời gian bắt đầu tại thời điểm này và sau đó xem xét khoảng thời gian bằng nhau ngay sau đó. Điều này dẫn đến kết quả rõ ràng, dễ hiểu và có thể là những gì sẽ được yêu cầu (ví dụ:người dùng không được vượt quá 100 lượt tải xuống mỗi ngày theo lịch). Tuy nhiên, điều này sẽ hoàn toàn bỏ sót các tình huống trong đó người dùng thực hiện 99 lượt tải xuống trong một giờ trước nửa đêm và 99 lượt tải xuống khác trong giờ đầu tiên của ngày mới.

Vì vậy, nếu kết quả được yêu cầu là "danh sách mười người tải xuống hàng đầu", thì đây là cách tiếp cận khác. Kết quả ở đây thoạt nhìn có thể không dễ hiểu vì một lần tải xuống có thể được tính vào nhiều khoảng thời gian. Điều này là do các khoảng thời gian sẽ (và cần) trùng nhau.

Đây là thiết lập của tôi. Tôi đã tạo bảng từ câu lệnh của bạn và thêm hai chỉ mục:

CREATE INDEX downloads_timestamp on downloads (dl_date);
CREATE INDEX downloads_user_id on downloads (user_id);

Dữ liệu tôi đã chèn vào bảng:

SELECT * FROM downloads;
+----+----------+---------+---------------------+
| id | stuff_id | user_id | dl_date             |
+----+----------+---------+---------------------+
|  1 |        1 |       1 | 2011-01-24 09:00:00 |
|  2 |        1 |       1 | 2011-01-24 09:30:00 |
|  3 |        1 |       1 | 2011-01-24 09:35:00 |
|  4 |        1 |       1 | 2011-01-24 10:00:00 |
|  5 |        1 |       1 | 2011-01-24 11:00:00 |
|  6 |        1 |       1 | 2011-01-24 11:15:00 |
|  7 |        1 |       1 | 2011-01-25 09:15:00 |
|  8 |        1 |       1 | 2011-01-25 09:30:00 |
|  9 |        1 |       1 | 2011-01-25 09:45:00 |
| 10 |        1 |       2 | 2011-01-24 08:00:00 |
| 11 |        1 |       2 | 2011-01-24 12:00:00 |
| 12 |        1 |       2 | 2011-01-24 12:01:00 |
| 13 |        1 |       2 | 2011-01-24 12:02:00 |
| 14 |        1 |       2 | 2011-01-24 12:03:00 |
| 15 |        1 |       2 | 2011-01-24 12:00:00 |
| 16 |        1 |       2 | 2011-01-24 12:04:00 |
| 17 |        1 |       2 | 2011-01-24 12:05:00 |
| 18 |        1 |       2 | 2011-01-24 12:06:00 |
| 19 |        1 |       2 | 2011-01-24 12:07:00 |
| 20 |        1 |       2 | 2011-01-24 12:08:00 |
| 21 |        1 |       2 | 2011-01-24 12:09:00 |
| 22 |        1 |       2 | 2011-01-24 12:10:00 |
| 23 |        1 |       2 | 2011-01-25 14:00:00 |
| 24 |        1 |       2 | 2011-01-25 14:12:00 |
| 25 |        1 |       2 | 2011-01-25 14:25:00 |
+----+----------+---------+---------------------+
25 rows in set (0.00 sec)

Như bạn có thể thấy, tất cả các lượt tải xuống đều diễn ra vào ngày hôm qua hoặc hôm nay và được thực hiện bởi hai người dùng khác nhau.

Bây giờ, những gì chúng ta phải lưu ý là những điều sau:Có (về mặt toán học) là vô hạn các khoảng thời gian 24 giờ (hoặc các khoảng thời gian bất kỳ khác) từ '2011-01-24 0:00' và '2011-01-25 23 :59:59 '. Nhưng vì độ chính xác của máy chủ là một giây, điều này giảm xuống còn 86.400 khoảng thời gian:

First interval:  2011-01-24 0:00:00 -> 2011-01-25 0:00:00
Second interval: 2011-01-24 0:00:01 -> 2011-01-25 0:00:01
Third interval: 2011-01-24 0:00:02 -> 2011-01-25 0:00:02
   .
   .
   .
86400th interval: 2011-01-24 23:59:59 -> 2011-01-25 23:59:59

Vì vậy, chúng tôi có thể sử dụng một vòng lặp để lặp lại tất cả các khoảng thời gian này và tính toán số lượt tải xuống trên mỗi người dùng và mỗi khoảng thời gian. Tất nhiên, không phải tất cả các khoảng thời gian đều được chúng tôi quan tâm như nhau, vì vậy chúng tôi có thể bỏ qua một số khoảng thời gian bằng cách sử dụng dấu thời gian trong bảng làm "đầu khoảng thời gian".

Đây là những gì truy vấn sau đây làm. Nó sử dụng mọi dấu thời gian tải xuống trong bảng làm "khoảng thời gian bắt đầu", thêm khoảng thời gian và sau đó truy vấn số lượt tải xuống cho mỗi người dùng trong khoảng thời gian này.

SET @duration = '24:00:00';
SET @limit = 5;
SELECT * FROM 
    (SELECT t1.user_id, 
            t1.dl_date startOfPeriod, 
            ADDTIME(t1.dl_date,@duration) endOfPeriod, 
           (SELECT COUNT(1) 
            FROM downloads t2 
            WHERE t1.user_id = t2.user_id 
            AND t1.dl_date <= t2.dl_date 
            AND ADDTIME(t1.dl_date,@duration) >= t2.dl_date) count
     FROM downloads t1) t3 
WHERE count > @limit;

Đây là kết quả:

+---------+---------------------+---------------------+-------+
| user_id | startOfPeriod       | endOfPeriod         | count |
+---------+---------------------+---------------------+-------+
|       1 | 2011-01-24 09:00:00 | 2011-01-25 09:00:00 |     6 |
|       1 | 2011-01-24 09:30:00 | 2011-01-25 09:30:00 |     7 |
|       1 | 2011-01-24 09:35:00 | 2011-01-25 09:35:00 |     6 |
|       1 | 2011-01-24 10:00:00 | 2011-01-25 10:00:00 |     6 |
|       2 | 2011-01-24 08:00:00 | 2011-01-25 08:00:00 |    13 |
|       2 | 2011-01-24 12:00:00 | 2011-01-25 12:00:00 |    12 |
|       2 | 2011-01-24 12:01:00 | 2011-01-25 12:01:00 |    10 |
|       2 | 2011-01-24 12:02:00 | 2011-01-25 12:02:00 |     9 |
|       2 | 2011-01-24 12:03:00 | 2011-01-25 12:03:00 |     8 |
|       2 | 2011-01-24 12:00:00 | 2011-01-25 12:00:00 |    12 |
|       2 | 2011-01-24 12:04:00 | 2011-01-25 12:04:00 |     7 |
|       2 | 2011-01-24 12:05:00 | 2011-01-25 12:05:00 |     6 |
+---------+---------------------+---------------------+-------+
12 rows in set (0.00 sec)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cập nhật cơ sở dữ liệu mysql từ hàng đã chọn datagridview

  2. điền hai trình quay từ cơ sở dữ liệu mysql phụ thuộc vào nhau

  3. ImportError:Không có mô-đun nào có tên là connector.conversion

  4. SQL:Lặp lại một hàng kết quả nhiều lần và đánh số các hàng

  5. Điểm chuẩn MySQL trên SSD:Công cụ và chiến lược