2009-10-22 37 views
6

Tôi sẽ vẽ đồ thị dữ liệu lưu trữ trong cơ sở dữ liệu MySQL và tôi cần một cách hiệu quả để có được các điểm dữ liệu có liên quan. Các bản ghi này được lưu trữ với ngày tháng dưới dạng int trong vài giây kể từ thời đại. Tôi muốn có thể một cái gì đó như:Nhóm MySQL theo khoảng thời gian trong một phạm vi ngày

Select SUM(bytes) from table where stime > x and stime < Y 
group by (10 second intervals) 

Có cách nào để thực hiện việc này không? hoặc, nó sẽ nhanh hơn để xử lý nó cục bộ trong python? ngay cả đối với một bảng hàng 500K?

EDIT Sai lầm của tôi, thời gian được lưu trữ dưới dạng dấu gấp đôi thay vì INT. Tôi hiện đang sử dụng GROUP BY (FLOOR(stime/I)) nơi tôi là khoảng thời gian mong muốn.

Trả lời

0

Tôi đã sử dụng đề xuất từ ​​cả câu trả lời và đồng nghiệp. Kết quả cuối cùng như sau:

Select FROM_UNIXTIME(stime), bytes 
from argusTable_2009_10_22 
where stime > (UNIX_TIMESTAMP()-600) 
group by floor(stime /10) 

Tôi đã thử giải pháp làm tròn, nhưng kết quả không nhất quán.

Cơ hội

2

Bạn đã thử những điều sau đây chưa? Chỉ cần chia cột tyiem cho 10 và làm tròn kết quả.

SELECT SUM(bytes) 
FROM  table 
WHERE  stime > x 
AND  stime < Y 
GROUP BY ROUND(stime/10, -1) 

Tôi không biết rằng chức năng ROUND() và nhóm với các cuộc gọi hàm hoạt động trong MySQL, mặc dù ở trên là T-SQL.

+0

tròn được đem lại cho tôi những khoảng thời gian rất khác nhau, trong khoảng thời gian mười phút tôi nhận được một số khoảng thời gian như nhỏ như 7 giây, và một số lớn như 1 phút ... – Chance

4

Bạn có thể thực hiện việc này bằng cách sử dụng phân chia số nguyên. Không chắc chắn về hiệu suất.

Để tôi là khoảng thời gian bạn muốn trong vài giây.

SELECT SUM(bytes), ((stime - X) DIV I) as interval 
FROM table 
WHERE (stime > X) and (stime < Y) 
GROUP BY interval 

Example, let X = 1500 and I = 10 
stime = 1503 -> (1503 - 1500) DIV 10 = 0 
stime = 1507 -> (1507 - 1500) DIV 10 = 0 
stime = 1514 -> (1514 - 1500) DIV 10 = 1 
stime = 1523 -> (1523 - 1500) DIV 10 = 2 
0

FLOOR trong nhóm đôi khi không thành công. đôi khi nhóm các thời điểm khác nhau dưới dạng một giá trị ví dụ khi bạn chia giá trị với 3 nhưng nó không giống nhau khi bạn chia với 4, mặc dù sự khác biệt giữa hai giá trị này lớn hơn 3 hoặc 4 mà nó nên nhóm thành hai nhóm khác nhau. Better đúc nó vào unsigned sau sàn mà hoạt động như:

CAST(FLOOR(UNIX_TIMESTAMP(time_field)/I) AS UNSIGNED INT) 

Vấn đề:

Đôi khi GROUP BY FLOOR(UNIX_TIMESTAMP(time_field)/3) cho nhóm ít so với GROUP BY FLOOR(UNIX_TIMESTAMP(time_field)/4) đó là toán học không nên có thể.

+1

Nó là toán học rất tốt có thể. Giả sử các giá trị là "3" và "4", sau đó chia cho 3 cả hai cho 1, trong khi chia cho 4 chúng cho 0 và 1. Vì vậy, nhóm theo/4 sẽ cung cấp nhiều nhóm hơn trong trường hợp này. – sth

0

Tôi đã làm điều này một vài thời gian trước đây, vì vậy tôi đã tạo ra một số chức năng (với máy chủ SQL, nhưng tôi cho rằng đó là gần như nhau):

Trước tiên tôi tạo ra một hàm vô hướng mà trả lại cho tôi ID của một ngày tùy thuộc trên một khoảng thời gian và một phần ngày (phút, giờ, ngày, bướm, năm):

CREATE FUNCTION [dbo].[GetIDDate] 
(
    @date datetime, 
    @part nvarchar(10), 
    @intervalle int 
) 
RETURNS int 
AS 
BEGIN 
    -- Declare the return variable here 
    DECLARE @res int 
    DECLARE @date_base datetime 
    SET @date_base = convert(datetime,'01/01/1970',103) 

    set @res = case @part 
       WHEN 'minute' THEN datediff(minute,@date_base,@date)/@intervalle 
       WHEN 'hour' THEN datediff(hour,@date_base,@date)/@intervalle 
       WHEN 'day' THEN datediff(day,@date_base,@date)/@intervalle 
       WHEN 'month' THEN datediff(month,@date_base,@date)/@intervalle 
       WHEN 'year' THEN datediff(year,@date_base,@date)/@intervalle 
       ELSE datediff(minute,@date_base,@date)/@intervalle END 



    -- Return the result of the function 
    RETURN @res 

END 

Sau đó, tôi tạo ra một hàm bảng trả về cho tôi tất cả các id betweend một phạm vi ngày:

CREATE FUNCTION [dbo].[GetTableDate] 
( 
    -- Add the parameters for the function here 
    @start_date datetime, 
    @end_date datetime, 
    @interval int, 
    @unite varchar(10) 
) 
RETURNS @res TABLE (StartDate datetime,TxtStartDate nvarchar(50),EndDate datetime,TxtEndDate nvarchar(50),IdDate int) 
AS 
begin 
    declare @current_date datetime 
    declare @end_date_courante datetime 
    declare @txt_start_date nvarchar(50) 
    declare @txt_end_date nvarchar(50) 
    set @current_date = case @unite 
       WHEN 'minute' THEN dateadd(minute, datediff(minute,0,@start_date),0) 
       WHEN 'hour' THEN dateadd(hour, datediff(hour,0,@start_date),0) 
       WHEN 'day' THEN dateadd(day, datediff(day,0,@start_date),0) 
       WHEN 'month' THEN dateadd(month, datediff(month,0,@start_date),0) 
       WHEN 'year' THEN dateadd(year, datediff(year,0,dateadd(year,@interval,@start_date)),0) 
       ELSE dateadd(minute, datediff(minute,0,@start_date),0) END 

    while @current_date < @end_date 
    begin 
     set @end_date_courante = 
      case @unite 
       WHEN 'minute' THEN dateadd(minute, datediff(minute,0,dateadd(minute,@interval,@current_date)),0) 
       WHEN 'hour' THEN dateadd(hour, datediff(hour,0,dateadd(hour,@interval,@current_date)),0) 
       WHEN 'day' THEN dateadd(day, datediff(day,0,dateadd(day,@interval,@current_date)),0) 
       WHEN 'month' THEN dateadd(month, datediff(month,0,dateadd(month,@interval,@current_date)),0) 
       WHEN 'year' THEN dateadd(year, datediff(year,0,dateadd(year,@interval,@current_date)),0) 
       ELSE dateadd(minute, datediff(minute,0,dateadd(minute,@interval,@current_date)),0) END 
     SET @txt_start_date = case @unite 
       WHEN 'minute' THEN CONVERT(VARCHAR(20), @current_date, 100) 
       WHEN 'hour' THEN CONVERT(VARCHAR(20), @current_date, 100) 
       WHEN 'day' THEN REPLACE(CONVERT(VARCHAR(11), @current_date, 106), ' ', '-') 
       WHEN 'month' THEN REPLACE(RIGHT(CONVERT(VARCHAR(11), @current_date, 106), 8), ' ', '-') 
       WHEN 'year' THEN CONVERT(VARCHAR(20), datepart(year,@current_date)) 
       ELSE CONVERT(VARCHAR(20), @current_date, 100) END 
     SET @txt_end_date = case @unite 
       WHEN 'minute' THEN CONVERT(VARCHAR(20), @end_date_courante, 100) 
       WHEN 'hour' THEN CONVERT(VARCHAR(20), @end_date_courante, 100) 
       WHEN 'day' THEN REPLACE(CONVERT(VARCHAR(11), @end_date_courante, 106), ' ', '-') 
       WHEN 'month' THEN REPLACE(RIGHT(CONVERT(VARCHAR(11), @end_date_courante, 106), 8), ' ', '-') 
       WHEN 'year' THEN CONVERT(VARCHAR(20), datepart(year,@end_date_courante)) 
       ELSE CONVERT(VARCHAR(20), @end_date_courante, 100) END 
     INSERT INTO @res (
StartDate, 
EndDate, 
TxtStartDate, 
TxtEndDate, 
IdDate) values(
@current_date, 
@end_date_courante, 
@txt_start_date, 
@txt_end_date, 
dbo.GetIDDate(@current_date,@unite,@interval) 
) 
     set @current_date = @end_date_courante 

    end 
    return 
end 

Vì vậy, nếu tôi muốn tính tất cả người dùng đã thêm cho mỗi khoảng thời gian 33 phút:

SELECT count(id_user) , timeTable.StartDate 
FROM user 
INNER JOIn dbo.[GetTableDate]('1970-01-01',datedate(),33,'minute') as timeTable 
ON dbo.getIDDate(user.creation_date,'minute',33) = timeTable.IDDate 

GROUP BY dbo.getIDDate (user.creation_date, 'phút', 33) ORDER BY timeTable.StartDate

:)

1
SELECT sec_to_time(time_to_sec(datefield)- time_to_sec(datefield)%(10)) as intervals,SUM(bytes) 
FROM table 
WHERE where stime > x and stime < Y 
group by intervals 
Các vấn đề liên quan