Frage

Ich bin Grafik-netflow-Daten in eine MySQL-Datenbank, und ich muss einen effizienten Weg, um die relevanten Daten Punkte.Diese Datensätze gespeichert sind, mit dem Datum als int für Sekunden seit der Epoche.Ich Möchte in der Lage sein, etwas wie:

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

Gibt es trotzdem, dies zu tun?oder, wäre es schneller zu handhaben es vor Ort in python?auch für 500K Zeile der Tabelle?

BEARBEITEN Mein Fehler, die Zeit wird gespeichert als unsigned double statt INT.Ich bin derzeit mit GROUP BY (FLOOR(stime / I)) wo ich das gewünschte Intervall.

War es hilfreich?

Lösung 5

Ich verwendet Anregungen aus beiden Antworten und ein Mitarbeiter.End-Ergebnis ist wie folgt:

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

Ich habe versucht, die Rundung Lösung, aber die Ergebnisse waren inkonsistent.

Chance

Andere Tipps

Sie können möglicherweise diese mit Integer-Division tun. Nicht sicher, ob der Leistung.

Lassen Sie mich Ihnen gewünschtes Intervall in Sekunden.

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

Haben Sie versucht, die folgenden? devide einfach die tyiem Säule um 10 und um das Ergebnis nach unten.

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

Ich weiß nicht, ob die Funktion ROUND () und mit der Funktion Gruppierung ruft Werke in MySQL aber die oben ist T-SQL.

FLOOR in Gruppe manchmal versagt. es manchmal Gruppen unterschiedliche Zeiten als ein Wert zum Beispiel, wenn Sie den Wert mit 3 teilen, aber es tut nicht das gleiche, wenn Sie mit 4 teilen, obwohl die Differenz zwischen diesen beiden Werten weit größer als 3 oder 4 ist, die es Gruppe sollte als zwei verschiedene Gruppen. Besser wirft es in unsigned nach Etage, die funktioniert wie:

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

Das Problem:

Manchmal gibt GROUP BY FLOOR(UNIX_TIMESTAMP(time_field)/3) weniger Gruppen im Vergleich zu GROUP BY FLOOR(UNIX_TIMESTAMP(time_field)/4) die mathematisch nicht möglich sein sollte.

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

Ich tat dies ein paar Mal vor, so erstellt ich eine Funktion (mit SQL-Server, aber ich nehme an, es ist fast das gleiche):

Zuerst habe ich eine skalare Funktion, die mir die ID eines Datums Rückkehr in Abhängigkeit von einem Intervall und einem Datumsteil (Minute, Stunde, Tag, Nachtfalter, Jahr):

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

Dann habe ich eine Tabellenfunktion, die mir alle id betweend Datumsbereich zurückgibt:

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

Also, wenn ich möchte das alle Benutzer für jedes Intervall von 33 Minuten gegeben zählen:

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, 'Minute', 33) ORDER BY timeTable.StartDate

:)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top