Как усреднить / суммировать данные за день в SQL Server 2005 - PullRequest
0 голосов
/ 17 сентября 2011

Я пытаюсь усреднить данные в SQL Server 2005 за день. Вот как будет выглядеть моя база данных, если я использую простой запрос как

SELECT timestamp, FEED
FROM ROASTER_FEED
ORDER timestamp

Данные:

timestamp               Feed    
02/07/2011 12:00:01     1246   
02/07/2011 12:00:01     1234    
02/07/2011 12:00:01     1387    
02/07/2011 12:00:02     1425   
02/07/2011 12:00:03     1263   
...    
02/07/2011 11:00:01     1153    
02/07/2011 11:00:01     1348    
02/07/2011 11:00:01     1387    
02/07/2011 11:00:02     1425    
02/07/2011 11:00:03     1223    
....   
03/07/2011 12:00:01     1226    
03/07/2011 12:00:01     1245    
03/07/2011 12:00:01     1384    
03/07/2011 12:00:02     1225    
03/07/2011 12:00:03     1363

Я не знаю, как усреднить фид, когда кто-то выбирает дату в месяце, и он отображает среднюю / сумму только за этот день.

Например, в результате, если я выберу день как 02/07/2011. Это дало бы мне что-то вроде этого:

02/07/2011 1234 (average value/or sum)

Ответы [ 8 ]

2 голосов
/ 17 сентября 2011

Одна возможность, если вам нужно делать это достаточно часто: добавьте три вычисляемых столбца для дня, месяца, года в вашу таблицу.Эти столбцы вычисляются автоматически на основе столбца timestamp, и они являются просто целочисленными значениями, поэтому их легко использовать в GROUP BY.

. Для этого используйте эти операторы T-SQL:

ALTER TABLE dbo.ROASTER_FEED ADD TSDay AS DAY(timestamp) PERSISTED
ALTER TABLE dbo.ROASTER_FEED ADD TSMonth AS MONTH(timestamp) PERSISTED
ALTER TABLE dbo.ROASTER_FEED ADD TSYear AS YEAR(timestamp) PERSISTED

Теперь вы можете легко выбирать свои данные в любой день, когда пожелаете:

SELECT TSDay, TSMonth, TSYear, SUM(FEED)   -- use AVG(FEED) for average values
FROM dbo.ROASTER_FEED
WHERE TSYear = 2011 AND TSMonth = 8   -- or whatever you want to grab from the table!
ORDER BY timestamp
GROUP BY TSDay, TSMonth, TSYear
1 голос
/ 01 октября 2011

7: 40 утра - 460 минут после 00:00

7: 40 вечера - 1180 минут после 00:00

середина 1440 минут после 00:00

И DATEPART (hh, SomeDate) * 60 + DATEPART (mi, SomeDate) дает вам количество минут после 00:00 для данной SomeDate

Итак, вы можете использовать:

SELECT
    AVG(Temperature) As Dayshift
FROM Drye_data
WHERE DATEPART(hh, TimeStamp)*60 + DATEPART(mi, TimeStamp) BETWEEN 460 AND 1180
      AND @SelectedDate = CAST(FLOOR(CAST(TimeStamp AS FLOAT)) AS DATETIME)

и для ночной смены:

    SELECT
    AVG(Temperature) As Nigthshift
FROM Drye_data
WHERE (
        (DATEPART(hh, TimeStamp)*60 + DATEPART(mi, TimeStamp) BETWEEN 0 AND 460)
        AND @SelectedDate = DATEADD(dd, 1, CAST(FLOOR(CAST(TimeStamp AS FLOAT)) AS DATETIME))
      )
      OR 
      (
         (DATEPART(hh, TimeStamp)*60 + DATEPART(mi, TimeStamp) BETWEEN 1180 AND 1440) AND @SelectedDate = CAST(FLOOR(CAST(TimeStamp AS FLOAT)) AS DATETIME)
      )
1 голос
/ 30 сентября 2011

Ну, я не SQL-парень, но я бы ожидал что-то вроде:

SELECT SUM(ValueColumn) AS Total, AVG(ValueColumn) AS Average FROM YourTableName
WHERE RecordedTime >= @StartTime AND RecordedTime < @EndTime

(где @StartTime и @EndTime - параметры, заполненные вызывающим кодом).

(мне не ясно, что произойдет, если записи не найдены ... стоит проверить.)

0 голосов
/ 07 ноября 2013

Ознакомьтесь с некоторыми уроками здесь http://www.smallsql.de/doc/sql-functions/date-time/index.html Я искал что-то simialr и нашел этот сайт полезным и подумал, что это может помочь

0 голосов
/ 17 сентября 2011

@ marc_s нашел предпочтительное решение использования вычисляемых столбцов, чтобы справиться с этим, но чтобы сделать это на лету, приведите данные вашей временной метки, чтобы убрать временную составляющую. В моем примере я привел его к 10-символьному полю, которое содержит дополненную до 0 дату.

;
WITH ROASTER_FEED ([timestamp],[Feed]) AS
(
SELECT CAST('02/07/2011 12:00:01' AS datetime),1246   
UNION ALL SELECT '02/07/2011 12:00:01',1234    
UNION ALL SELECT '02/07/2011 12:00:01',1387    
UNION ALL SELECT '02/07/2011 12:00:02',1425   
UNION ALL SELECT '02/07/2011 12:00:03',1263   

UNION ALL SELECT '02/07/2011 11:00:01',1153    
UNION ALL SELECT '02/07/2011 11:00:01',1348    
UNION ALL SELECT '02/07/2011 11:00:01',1387    
UNION ALL SELECT '02/07/2011 11:00:02',1425    
UNION ALL SELECT '02/07/2011 11:00:03',1223    

UNION ALL SELECT '03/07/2011 12:00:01',1226    
UNION ALL SELECT '03/07/2011 12:00:01',1245    
UNION ALL SELECT '03/07/2011 12:00:01',1384    
UNION ALL SELECT '03/07/2011 12:00:02',1225    
UNION ALL SELECT '03/07/2011 12:00:03',1363
)
SELECT
    -- Shear off the time value by forcing the date into date values
    -- If this was SQL Server 2008+, we'd just cast to date type and
    -- be done with it
    -- Chart for convert options
    -- http://msdn.microsoft.com/en-us/library/ms187928.aspx
    CONVERT(char(10), RF.[timestamp], 121) AS [timestamp]
,   COUNT(1) AS row_counts
,   SUM(RF.Feed) as ValuesSum 
,   AVG(RF.Feed) as Average
FROM 
    ROASTER_FEED RF
GROUP BY
    CONVERT(char(10), RF.[timestamp], 121)    

Результаты в

timestamp   row_counts   ValuesSum  Average
2011-02-07  10           13091      1309
2011-03-07  5            6443       1288
0 голосов
/ 17 сентября 2011

попробуйте это:

SELECT timestamp, sum(FEED)
FROM ROASTER_FEED
WHERE timestamp=....
GROUP BY timestamp

это может быть медленно, если вы обрабатываете много данных, в этом случае вам следует рассмотреть дополнительную таблицу, которая содержит предварительно рассчитанные значения для каждого дня.

0 голосов
/ 17 сентября 2011

Чтобы получить средний корм за один день, вы можете использовать это.

declare @Date datetime

set @Date = '20110702'

select @Date as [timestamp], avg(FEED) as AvgFeed
from ROASTER_FEED
where [timestamp] >= @Date and 
      [timestamp] < dateadd(day, 1, @Date)
0 голосов
/ 17 сентября 2011
SELECT COUNT(timestamp) as NumValues, 
       SUM(Feed) as ValuesSum, 
       AVG(Feed) as Average

  FROM ROASTER_FEED

 WHERE timestamp BETWEEN '1/1/2011'  AND '9/15/2011'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...