2012-02-16 31 views
5

Tôi gần như phát điên khi cố gắng giải quyết vấn đề này:Truy vấn SQL để đếm số người dùng đã đăng ký mỗi ngày

Trong người dùng ứng dụng của tôi có thể đăng ký và xóa chính họ. Ngày tạo và ngày xóa được lưu giữ trong cơ sở dữ liệu dưới dạng dấu thời gian. Tôi cần phải biết cho mỗi ngày trong một loạt các ngày, có bao nhiêu người dùng đã đăng ký và không bị xóa tồn tại vào ngày đó.

Vì vậy, nếu tôi có 10 người dùng hiện tại vào ngày 2012-02-01, một người dùng đã xóa tài khoản vào 2012-02-03, ba người dùng đã đăng ký vào 2012-02-04 và hai người dùng đã xóa vào 2012-02- 06, và truy vấn tổng số người dùng đã đăng ký từ 2012-02-01 cho đến 2012-02-07 Tôi muốn nhận được kết quả như sau:

 
day    total_users 
2012-02-01  10 
2012-02-02  10 
2012-02-03  9 
2012-02-04  12 
2012-02-05  12 
2012-02-06  10 
2012-02-07  10 

Đây là cách bảng người dùng đơn giản của tôi trông giống như:

user_id, user_name, created_at, deleted_at

Không có vấn đề gì để lấy số o e đã đăng ký và không phải người dùng xóa một ngày cụ thể (ở đây 2012/02/01, mà sẽ làm cho tôi 10 trong ví dụ của tôi):

select application.application_id as application_id, count(user.user_id) as user_total 
from application, user 
where application.application_id = user.application_id 
and date(user.created_at) <= '2012-02-01' 
and ((date(user.deleted_at) > '2012-02-01') or (user.deleted_at is null)) 

Ai có một đầu mối làm thế nào tôi có thể tạo ra một truy vấn (mà không có một con trỏ) sẽ có kết quả mong đợi của tôi? Cơ sở dữ liệu của tôi là một MySQL 5.0.51 trên Debian.

Cảm ơn trước Marcus

Trả lời

2

Nếu bạn có một bảng với một danh sách các ngày trong nó (gọi là cái gì đó như lịch), bạn có thể sử dụng một truy vấn như thế này:

select c.calendar_date, count(*) user_total 
from calendar c 
left join user u 
     on date(u.created_at) <= c.calendar_date and 
      (date(u.deleted_at) > c.calendar_date or u.deleted_at is null) 
group by c.calendar_date 

Nếu bạn không có bảng có danh sách các ngày trong đó, bạn có thể mô phỏng một bảng có chứa truy vấn sau:

select * from 
(select adddate('1970-01-01',t4.i*10000 + t3.i*1000 + t2.i*100 + t1.i*10 + t0.i) calendar_date from 
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t0, 
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t1, 
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t2, 
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t3, 
(select 0 i union select 1 union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9) t4) v 
where calendar_date between ? /*start of date range*/ and ? /*end of date range*/ 
+0

Cảm ơn bạn rất nhiều, điều này hoạt động hoàn hảo! Tôi chỉ phải thay thế "i" trong mỗi dòng với t0, t1 vv, tôi nghĩ rằng đây là lỗi máy chủ MySQL cũ của tôi. –

+0

@MarcusMuench: Rất tiếc, lỗi của tôi. Tôi đã sửa chữa truy vấn - cảm ơn. –

2
SELECT date(user.created_at) as "creation_date", count(user.user_id) as "user_total" 
FROM application a 
INNER JOIN user u ON a.application_id = u.application_id 
WHERE date(user.created_at) <= '2012-02-01' 
AND ((date(user.deleted_at) > '2012-02-01') or (user.deleted_at is null)) 
GROUP BY date(user.created_at) 
ORDER BY date(user.created_at) ASC 
+0

+1. @ user1214154, hãy nhớ rằng điều này sẽ không liệt kê những ngày không có bất kỳ người dùng đã đăng ký nào vào ngày đó với số lần là 0. nó sẽ chỉ xuất ra những ngày tồn tại trong bảng – talereader

+0

Điều này sẽ không trả về số lượng người dùng đã đăng ký mỗi ngày - thay vào đó, nó sẽ trả về số người dùng đã đăng ký * trên * mỗi ngày. Do dữ liệu mẫu được mô tả trong câu hỏi, nó sẽ không tạo ra kết quả được yêu cầu - thay vào đó, nó sẽ tạo ra một số người dùng và ngày trước 2012-02-01 (thêm tối đa 10 người dùng), và không có gì sau năm 2012- 02-01. –

Các vấn đề liên quan