Cố gắng áp dụng mã này để công việc của bạn -
CREATE TABLE visits(
user_id INT(11) NOT NULL,
dt DATETIME DEFAULT NULL
);
INSERT INTO visits VALUES
(1, '2011-06-30 12:11:46'),
(1, '2011-07-01 13:16:34'),
(1, '2011-07-01 15:22:45'),
(1, '2011-07-01 22:35:00'),
(1, '2011-07-02 13:45:12'),
(1, '2011-08-01 00:11:45'),
(1, '2011-08-05 17:14:34'),
(1, '2011-08-05 18:11:46'),
(1, '2011-08-06 20:22:12'),
(2, '2011-08-30 16:13:34'),
(2, '2011-08-31 16:13:41');
SET @i = 0;
SET @last_dt = NULL;
SET @last_user = NULL;
SELECT v.user_id,
COUNT(DISTINCT(DATE(dt))) number_of_days,
MAX(days) number_of_visits
FROM
(SELECT user_id, dt
@i := IF(@last_user IS NULL OR @last_user <> user_id, 1, IF(@last_dt IS NULL OR (DATE(dt) - INTERVAL 1 DAY) > DATE(@last_dt), @i + 1, @i)) AS days,
@last_dt := DATE(dt),
@last_user := user_id
FROM
visits
ORDER BY
user_id, dt
) v
GROUP BY
v.user_id;
----------------
Output:
+---------+----------------+------------------+
| user_id | number_of_days | number_of_visits |
+---------+----------------+------------------+
| 1 | 6 | 3 |
| 2 | 2 | 1 |
+---------+----------------+------------------+
Giải thích:
Để hiểu cách thức hoạt động chúng ta hãy kiểm tra các subquery, ở đây nó được.
SET @i = 0;
SET @last_dt = NULL;
SET @last_user = NULL;
SELECT user_id, dt,
@i := IF(@last_user IS NULL OR @last_user <> user_id, 1, IF(@last_dt IS NULL OR (DATE(dt) - INTERVAL 1 DAY) > DATE(@last_dt), @i + 1, @i)) AS
days,
@last_dt := DATE(dt) lt,
@last_user := user_id lu
FROM
visits
ORDER BY
user_id, dt;
Khi bạn thấy truy vấn trả về tất cả các hàng và thực hiện xếp hạng cho số lượt truy cập. Đây là phương thức xếp hạng được biết dựa trên các biến, lưu ý rằng các hàng được sắp xếp theo trường người dùng và ngày tháng. Truy vấn này tính toán dùng truy cập, và kết quả tiếp theo dữ liệu thiết lập nơi days
cột cung cấp thứ hạng cho số lần truy cập -
+---------+---------------------+------+------------+----+
| user_id | dt | days | lt | lu |
+---------+---------------------+------+------------+----+
| 1 | 2011-06-30 12:11:46 | 1 | 2011-06-30 | 1 |
| 1 | 2011-07-01 13:16:34 | 1 | 2011-07-01 | 1 |
| 1 | 2011-07-01 15:22:45 | 1 | 2011-07-01 | 1 |
| 1 | 2011-07-01 22:35:00 | 1 | 2011-07-01 | 1 |
| 1 | 2011-07-02 13:45:12 | 1 | 2011-07-02 | 1 |
| 1 | 2011-08-01 00:11:45 | 2 | 2011-08-01 | 1 |
| 1 | 2011-08-05 17:14:34 | 3 | 2011-08-05 | 1 |
| 1 | 2011-08-05 18:11:46 | 3 | 2011-08-05 | 1 |
| 1 | 2011-08-06 20:22:12 | 3 | 2011-08-06 | 1 |
| 2 | 2011-08-30 16:13:34 | 1 | 2011-08-30 | 2 |
| 2 | 2011-08-31 16:13:41 | 1 | 2011-08-31 | 2 |
+---------+---------------------+------+------------+----+
Sau đó, chúng tôi nhóm dữ liệu này được thiết lập bởi người sử dụng và sử dụng chức năng tổng hợp: 'COUNT (DISTINCT (DATE (dt))) '- đếm số ngày ' MAX (ngày) '- số lượt truy cập, đây là giá trị tối đa cho trường days
từ truy vấn phụ của chúng tôi.
Đó là tất cả;)
Về khía cạnh đầu tiên ... Tôi dường như không hiểu hoàn toàn đề xuất của bạn ... để cung cấp thêm một số chi tiết? Cảm ơn bạn! Về câu hỏi thứ hai, truy vấn của tôi là đúng, miễn là bạn không tính người dùng và thành phố, như được đề cập trong câu hỏi của tôi. – linkyndy
Xin lỗi, tôi giả định rằng kết quả cho "số ngày người dùng ở trong thành phố" sẽ trông giống như (user_id, count_of_days). – Simon
Cảm ơn bạn đã biết chi tiết. Với một số điều chỉnh để phù hợp với bảng cơ sở dữ liệu thực tế của tôi, truy vấn của bạn hoạt động như một sự quyến rũ. Cám ơn bạn một lần nữa! – linkyndy