按日期汇总和分组

时间:2012-08-24 06:54:42

标签: mysql group-by sum

我有一个看起来像这样的表:

ID  t_stamp         views uviews hits uhits
1   7/18/2012 19:00 105   11     0    0
5   7/18/2012 20:00 1     1      0    0
2   7/19/2012 9:00  118   4      0    0
1   7/19/2012 10:00 196   18     0    0
7   7/19/2012 11:00 2     1      0    0
2   7/19/2012 12:00 38    11     0    0
2   7/19/2012 13:00 20    5      0    0
2   7/19/2012 19:00 9     2      0    0
2   7/20/2012 15:00 85    6      0    0
1   7/20/2012 16:00 483   101    2    2
2   7/20/2012 17:00 1200  240    0    0
2   7/20/2012 18:00 1200  232    0    0
2   7/20/2012 19:00 1199  231    0    0
2   7/20/2012 20:00 1200  236    0    0
2   7/20/2012 21:00 1201  237    0    0
1   7/20/2012 22:00 1220  187    0    0
1   7/20/2012 23:00 869   165    0    0

我的方法是将它们组合在一起,这样我就可以获得最后四列中的每一列的SUM。 ID并不重要。

我正在使用它:

SELECT `bannerID` , DATE_FORMAT( `t_stamp` , '%m/%d/%Y' ) AS `date` ,
SUM( `views` ) AS `views` , SUM( `uviews` ) AS `uviews` , SUM( `hits` ) AS `hits` , SUM( `uhits` ) AS `uhits`
FROM test_bannerstats
WHERE DATE( t_stamp ) >= DATE( '2012-07-01' )
AND DATE( t_stamp ) <= DATE( '2012-08-24' )
GROUP BY `date`
ORDER BY `date` ASC

然而,这对我来说似乎不正确,因为数字似乎相互矛盾。最后,我希望每天获得最后四列的每日记录。

编辑:

它看起来是时区问题!我会告诉你为什么......

请看上面的表格,现在让我们做一整天的补充......

1   07/18/2012  106     12    0     0
1   07/19/2012  383     41    0     0
1   07/20/2012  8657    1635  2     2

以上是正确的。以下是错误的。

1   07/18/2012  105     11    0     0
1   07/19/2012  384     42    0     0
1   07/20/2012  4167    810   2     2

问题?晚上8点之后的任何事情都会发生在第二天。这是一个时区问题,我必须解决它。

4 个答案:

答案 0 :(得分:0)

尝试这个,

SELECT  DATE_FORMAT(DATE(t_stamp), '%m/%d/%Y') AS `date`,
        SUM(views) totalViews,
        SUM(uviews) totalUViews,
        SUM(hits) totalHits,
        SUM(uhits) totalUHits,
FROM    tableName
WHERE   DATE( t_stamp ) >= DATE( '2012-07-01' ) AND 
            DATE( t_stamp ) <= DATE( '2012-08-24' )
GROUP BY DATE(t_stamp)
ORDER BY `date` ASC

答案 1 :(得分:0)

您的查询可以简化为:

SELECT `bannerID`,
        DATE_FORMAT( `t_stamp` , '%m/%d/%Y' ) AS `date`,
        SUM( `views` ) AS `views`,
        SUM( `uviews` ) AS `uviews`,
        SUM( `hits` ) AS `hits`,
        SUM( `uhits` ) AS `uhits`
FROM    test_bannerstats
WHERE   DATE( t_stamp ) BETWEEN '2012-07-01' AND '2012-08-24'
GROUP BY DATE(t_stamp)
ORDER BY DATE(t_stamp) ASC;

答案 2 :(得分:0)

  • 如果要为索引提供使用机会,请尽可能避免在列上使用函数。替换条件:

    WHERE DATE( t_stamp ) >= DATE( '2012-07-01' )
      AND DATE( t_stamp ) <= DATE( '2012-08-24' )`
    

    with:

    WHERE t_stamp >= DATE( '2012-07-01' )
      AND t_stamp < DATE( '2012-08-25' )
    
  • 您可以在date列表中定义别名SELECT。此别名不能在WHEREGROUP BY子句中使用(说实话,它可以在GROUP BY子句中使用,但我不建议使用它)。而不是:

    GROUP BY `date`
    

    使用:

    GROUP BY DATE(t_stamp)
    
  • GROUP BYORDER BY在同一表达式上完成时,可以使用专有的MySQL语法(您可以在SELECT文档中阅读)。而不是:

    GROUP BY DATE(t_stamp)
    ORDER BY DATE(t_stamp) ASC;
    

    你可以使用(为了获得轻微的效率):

    GROUP BY DATE( t_stamp ) ASC ;
    

查询现在变为:

SELECT 
    bannerID
  , DATE_FORMAT( DATE( t_stamp ), '%m/%d/%Y' ) AS `date` 
  , SUM( views ) AS views
  , SUM( uviews ) AS uviews
  , SUM( hits ) AS hits
  , SUM( uhits ) AS uhits
FROM 
    test_bannerstats
WHERE 
    t_stamp >= DATE( '2012-07-01' )
  AND 
    t_stamp < DATE( '2012-08-25' )     --- notice the `<` and the +1 date offset
GROUP BY
    DATE( t_stamp ) ASC ;

答案 3 :(得分:0)

我认为你的SQL查询不会真正起作用,这只适用于7月1日到8月24日。如果最后4个日期超出该日期怎么办?它不会接受任何东西。

在我看来,最好的办法是:

  SELECT SUM(column_name) FROM table_name order by id DESC limit 4;

按ID desc排序将按降序对结果进行排序。限制4,只会获得前4个结果。

希望有所帮助。