简体   繁体   English

Mysql选择上周每天的用户帖子总数

[英]Mysql select total Count of posts of a user day by day for last week

currently i'm using php/mysql and part of project i show to user his total count of posts he posted in website, count of today's posts, and count of ppl following him 目前,我正在使用php / mysql和项目的一部分,我向用户显示他在网站上发布的帖子总数,今天的帖子数以及关注他的ppl数量

For that currently im doing 对于目前我正在做的

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");

This query give me 3 number, of Total posts, today posts and Total followers following user 该查询给我3个帖子,共计帖子总数,今日帖子和关注用户的关注者总数

the point is i want to show a bar chart next to this number that represent the user activity over past week (curve or bar chart that can tell user if he's droping of increasing etc..) 关键是我想在此数字旁边显示一个条形图 ,以代表过去一周的用户活动(曲线或条形图可以告诉用户他的下降幅度是否在增加等。)

example this query now returns 此查询现在返回的示例

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

but because i also need the bar chart now presenting his post counts over days. 但是因为我现在还需要条形图来显示他过去几天的帖子数。 i did 我做到了

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 |

in where tps(1) represent WHERE posts was posted before current date - 1 day. 其中tps(1)代表WHERE帖子是在当前日期-1天之前发布的。

so how can i do such loop in statement ? 那我该如何在语句中循环呢? or do should i keep it like that? 还是我应该那样保留它?

currently its not causing much of a trouble. 目前,它不会造成太大的麻烦。 0.0008 sec excution time so its great. 0.0008秒的执行时间非常棒。

yet is there a better way to do it ? 还有更好的方法吗?

i looks stupid :p 我看起来很蠢:p

thanks in advance 提前致谢

EDIT 编辑

For future googlers. 对于未来的谷歌人。

i ended up doing 我最终做了

$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;
}

So i ended up with letting php handling it for sake of execution time. 所以我最终还是让php为执行时间着手处理它。

I would alter via the sample below. 我将通过以下示例进行更改。 By the select() SQLVars will pre-compute each of the days once before joining to the "posts" table. 通过select(),SQLVars将在加入“ posts”表之前的每一天进行一次预计算。 Now the SUM( case/when ) will only need to compare to that "@Day?" 现在,SUM(case / when)仅需要与“ @Day?”进行比较。 value. 值。 Since it is all for the same user, I just put that into the where clause so it doesn't need to consider anyone else. 由于所有操作都是针对同一用户的,因此我将其放在where子句中,因此不需要考虑其他任何人。

Now, one thing I noticed in what you have, and don't know if its intentional, or not. 现在,我注意到您所拥有的一件事,并且不知道它是否是有意的。 But since you are requerying the exact set of rows each time, but for the different <= date range, all your counts would be incremental of the prior. 但是,由于您每次都在重新查询确切的行集,但是对于不同的<=日期范围,所有的计数都将是前一个的增量。 Ex: All rows prior to 1 day ago will be AT LEAST everything from 7 + 6 + 5 + 4 + 3 + 2 days ago. 例如:1天前的所有行将至少是7 + 6 + 5 + 4 + 3 + 2天前的所有行。 Similar for 2 days ago will be AT LEAST everything from 7 + 6 + 5 + 4 + 3 days ago. 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

If what you really wanted was how many actual posts ex: from Today, Just one Day ago, Just TWO days ago, Just THREE days ago you would have to adjust your query to remove the <= to only "=" 如果您真正想要的是多少实际帖子,例如:从今天,一天前,两天前,三天前,您就必须调整查询以将<=删除为仅“ =”

Ex: assume the following week of activity of actual posts. 例如:假设接下来一周的实际职位活动。

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

If you expect the chart to show that (in this example), each day had their respective counts, just change from "<=" to "=". 如果您希望图表显示出来(在此示例中),则每天都有各自的计数,只需将其从“ <=”更改为“ =“。

Overall a slight difference from your query where it processes each field every time. 总体而言,它与每次处理每个字段的查询略有不同。 This query process 1 record and accounts for all column result values. 此查询过程1记录并说明所有列结果值。 Just another option to a solution you have. 这是您拥有的解决方案的另一种选择。 I don't know performance impact on such a small table, but it might be more measurable if you have someone with 1000's of post activity. 我不知道性能对这么小的桌子有什么影响,但是如果您的某人的活动后活动数为1000,则可能更可衡量。

You can simplify your sql and use this instead. 您可以简化您的sql并改用它。 It will give you all the counts of the posts posted in the decreasing order of the dates. 它会为您提供按日期降序发布的所有帖子数。 So you will have all the past 7 days post. 因此,您将拥有过去7天的所有帖子。 Now in your application login you just need to handle this data. 现在,在您的应用程序登录名中,您只需要处理这些数据。 This will simplify your sql and make it perform efficiently. 这将简化您的sql并使其高效执行。

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

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM