Mysql选择上周用户日期的总计数

时间:2013-05-15 16:21:07

标签: mysql count aggregate-functions

目前我正在使用php / mysql和项目的一部分我向用户展示他在网站上发布的帖子总数,今天的帖子数量以及跟随他的人数

目前我正在做的

SELECT
(SELECT COUNT(*) FROM posts WHERE userId='{$u->id}) as totalposts,
(SELECT COUNT(*) FROM posts WHERE userId='{$u->id} and DATE(datePosted) = DATE(NOW())) as todayposts,
(SELECT COUNT(*) FROM user_follower WHERE followedId='{$u->id}') as myfollowers");

此查询为我提供了3个帖子总数,今天的帖子以及跟随用户的总关注者

关键是,我希望在此数字旁边显示一个条形图,表示过去一周的用户活动(曲线或条形图可以告诉用户他是否正在增加等等...)

示例此查询现在返回

totalposts|todayposts|myfollowers|
100       | 4        | 300       |

但是因为我现在还需要条形图来显示他的帖子数量超过几天。我做了

SELECT
          (SELECT COUNT(*) FROM posts WHERE userId=2) as tpT,
          (SELECT COUNT(*) FROM posts WHERE userId=2 and DATE(timePosted) <= DATE(NOW()) - INTERVAL 1 DAY ) as tp1,
          (SELECT COUNT(*) FROM posts WHERE userId=2 and DATE(timePosted) <= DATE(NOW()) - INTERVAL 2 DAY ) as tp2,
          (SELECT COUNT(*) FROM posts WHERE userId=2 and DATE(timePosted) <= DATE(NOW()) - INTERVAL 3 DAY ) as tp3,
          (SELECT COUNT(*) FROM posts WHERE userId=2 and DATE(timePosted) <= DATE(NOW()) - INTERVAL 4 DAY ) as tp4,
          (SELECT COUNT(*) FROM posts WHERE userId=2 and DATE(timePosted) <= DATE(NOW()) - INTERVAL 5 DAY ) as tp5,
          (SELECT COUNT(*) FROM posts WHERE userId=2 and DATE(timePosted) <= DATE(NOW()) - INTERVAL 6 DAY ) as tp6,
          (SELECT COUNT(*) FROM posts WHERE userId=2 and DATE(timePosted) <= DATE(NOW()) - INTERVAL 7 DAY ) as tp7,
          (SELECT COUNT(*) FROM posts WHERE userId=2 and DATE(timePosted) = DATE(NOW())) as tdvT

Result
tpT|tp1|tp2|tp3|tp4|tp5|tp6|
100|96 | 90| 90| 89|80 |64 |

,其中tps(1)表示在当前日期之前发布了帖子的帖子 - 1天。

那我怎么能在声明中做这样的循环呢?或者我应该这样做吗?

目前它没有造成太大麻烦。 0.0008秒的执行时间非常棒。

还有更好的方法吗?

我看起来很蠢:p

提前致谢

修改

对于未来的googlers。

我最终做了

$v=$this->db->query("SELECT count(*) as count,date(timePosted) as day FROM `posts` where userId = {$u->id} group by date(timePosted)");

$pts=[];

for($i=0; $i <= 6; $i++){
    $pts[date('Y-m-d',strtotime(date('Y-m-d')."- $i Day"))]='0';
    $vs[date('Y-m-d',strtotime(date('Y-m-d')."- $i Day"))]='0';
}

foreach($v->result() as $s){
if(isset($vs[$s->day]))$vs[$s->day]=$s->count;
}

所以我最终为了执行时间而让php处理它。

2 个答案:

答案 0 :(得分:3)

我会通过以下示例进行更改。通过select(),SQLVars将在加入“posts”表之前预先计算每一天。现在SUM(case / when)只需要与那个“@Day?”进行比较。值。因为它全部是针对同一个用户的,所以我只是把它放到where子句中,所以不需要考虑其他任何人。

现在,我注意到你所拥有的一件事,并且不知道它是否有意或无意。但是,由于您每次都要重新查找确切的行集,但是对于不同的&lt; =日期范围,您的所有计数都将是先前的增量。例如:1天前的所有行将至少从7 + 6 + 5 + 4 + 3 + 2天前的所有行。类似的2天前将是至少7 + 6 + 5 + 4 + 3天前的所有内容。

select
      count(*) tpT,
      sum( case when date(p.timePosted) = @Day0 then 1 else 0 end ) as tdvT,
      sum( case when date(p.timePosted) <= @Day1 then 1 else 0 end ) as TP1,
      sum( case when date(p.timePosted) <= @Day2 then 1 else 0 end ) as TP2,
      sum( case when date(p.timePosted) <= @Day3 then 1 else 0 end ) as TP3,
      sum( case when date(p.timePosted) <= @Day4 then 1 else 0 end ) as TP4,
      sum( case when date(p.timePosted) <= @Day5 then 1 else 0 end ) as TP5,
      sum( case when date(p.timePosted) <= @Day6 then 1 else 0 end ) as TP6,
      sum( case when date(p.timePosted) <= @Day7 then 1 else 0 end ) as TP7
   from
      posts p,
      ( select @Day0 := date( now()),
               @Day1 := date_add( date(now()), interval -1 day ),
               @Day2 := date_add( date(now()), interval -2 day ),
               @Day3 := date_add( date(now()), interval -3 day ),
               @Day4 := date_add( date(now()), interval -4 day ),
               @Day5 := date_add( date(now()), interval -5 day ),
               @Day6 := date_add( date(now()), interval -6 day ),
               @Day7 := date_add( date(now()), interval -7 day ) ) SQLVars
   where 
      p.userID = 2

如果您真正想要的是有多少实际帖子来自:来自 今天,就在前一天,就在两天前,就在三天前你必须调整你的查询以删除&lt; = to only“=”

Ex:假设下一周的实际帖子活动。

Even before this Sunday,    Sun  Mon  Tue  Wed  Thu  Fri Sat
 200                         10   20   30   20   10   50  60


Using the <= approach your 
TP1 (representing Saturday 1 day ago) would be 400.  
TP2 (2 days ago -- Friday and prior) would be 340, 
TP3 (3 days ago -- Thursday and prior) would be 290, etc

如果您希望图表显示(在此示例中),每天都有各自的计数,只需将“&lt; =”更改为“=”。

整体上与您的查询略有不同,每次都会处理每个字段。此查询过程1记录并记录所有列结果值。您拥有解决方案的另一种选择。我不知道对这样一个小桌子的性能影响,但如果你有1000个帖子活动的人,它可能更容易测量。

答案 1 :(得分:2)

您可以简化您的SQL并使用它。它将按日期的递减顺序为您提供所有帖子的计数。因此,您将在过去7天内发布所有内容。现在,在您的应用程序登录中,您只需要处理这些数据。这将简化您的SQL并使其高效运行。

    select count(*)
    from posts
    where userId=2
    group by DATE(timePosted)
    order by DATE(timePosted) desc
    limit 7

希望这有帮助。