2012-05-24 2 views
11

Tôi có một số bài đăng được lưu vào bảng InnoDB trên MySQL. Bảng có các cột "id", "date", "user", "content". Tôi muốn thực hiện một số đồ thị thống kê, vì vậy tôi đã kết thúc bằng cách sử dụng truy vấn sau đây để có được số lượng bài mỗi giờ của ngày hôm qua:Bài đăng trung bình mỗi giờ trên MySQL?

SELECT HOUR(FROM_UNIXTIME(`date`)) AS `hour`, COUNT(date) from fb_posts 
WHERE DATE(FROM_UNIXTIME(`date`)) = CURDATE() - INTERVAL 1 DAY GROUP BY hour 

này kết quả đầu ra các dữ liệu sau:

table data

tôi có thể chỉnh sửa truy vấn này để nhận được bất kỳ ngày nào tôi muốn. Nhưng những gì tôi muốn bây giờ là AVERAGE của mỗi giờ mỗi ngày, để nếu vào Ngày 1 vào lúc 00 giờ tôi có 20 bài đăng và vào Ngày 2 lúc 00 giờ tôi có 40, tôi muốn đầu ra là "30". Tôi cũng muốn có thể chọn thời gian ngày nếu có thể.

Cảm ơn trước!

Trả lời

6

Bạn có thể sử dụng truy vấn phụ để nhóm dữ liệu theo ngày/giờ, sau đó tính trung bình theo giờ trên truy vấn phụ.

Dưới đây là một ví dụ để cung cấp cho bạn các tính trung bình theo giờ trong 7 ngày qua:

select the_hour,avg(the_count) 
from 
(
    select date(from_unixtime(`date`)) as the_day, 
    hour(from_unixtime(`date`)) as the_hour, 
    count(*) as the_count 
    from fb_posts 
    where `date` >= unix_timestamp(current_date() - interval 7 day) 
    and created_on < unix_timestamp(current_date()) 
    group by the_day,the_hour 
) s 
group by the_hour 
+0

tại sao bạn thêm "s" sau truy vấn phụ (...)? –

+1

Đó là bí danh cho truy vấn phụ, được yêu cầu trong MySQL để tránh lỗi này: 'ERROR 1248 (42000): Mỗi bảng dẫn xuất phải có bí danh riêng của nó'. Bạn có thể tiết lộ nhiều hơn nếu bạn muốn và sử dụng một cái gì đó như 'như sub_query'. –

+0

Ồ, tôi hiểu rồi. Mặc dù giải pháp Linoff rất giống nhau, đây là giải pháp giúp tôi hiểu nhiều hơn về SQL. Cảm ơn! –

0

tổng hợp các thông tin theo ngày và giờ, và sau đó lấy trung bình theo giờ:

select hour, avg(numposts) 
from (SELECT date(`date`) as day, HOUR(FROM_UNIXTIME(`date`)) AS `hour`, 
      count(*) as numposts 
     from fb_posts 
     WHERE DATE(FROM_UNIXTIME(`date`)) between <date1> and <date2> 
     GROUP BY date(`date`), hour 
    ) d 
group by hour 
order by 1 

By the way, tôi thích bao gồm trình tự rõ ràng bởi vì hầu hết các cơ sở dữ liệu không đặt kết quả của một nhóm bởi. Mysql là một cơ sở dữ liệu.

+0

Vì lợi ích của hiệu suất, bạn nên áp dụng các hàm cho các giá trị đầu vào (không phải cột ngày) trong mệnh đề where của truy vấn con của bạn. –

+0

Ngoài ra, kết quả được sắp xếp hoàn toàn bởi nhóm, do đó, thứ tự không cần thiết nếu đó là thứ tự bạn muốn. –

+2

Điều này có vẻ đúng với mysql. ANSI SQL khá cụ thể mà nhóm theo kết quả không được sắp xếp (mặc dù chúng thường được thực hành). Tôi hy vọng rằng mysql đủ thông minh để bỏ qua mệnh đề "order by" nếu nó không cần thực hiện công việc. –

0
SELECT 
    HOUR(FROM_UNIXTIME(`date`)) AS `hour` 
    , COUNT(`id`) \ COUNT(DISTINCT TO_DAYS(`date`)) AS avgHourlyPostCount 
FROM fb_posts 
WHERE `date` > '2012-01-01' -- your optional date criteria 
GROUP BY hour 

này cung cấp cho bạn một số lượng của tất cả các bài viết, chia cho số ngày, theo giờ .