0

目前我正在使用 php/mysql 和项目的一部分,我向用户展示了他在网站上发布的帖子总数、今天的帖子数以及关注他的 ppl 数

对于目前我正在做的

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) 代表 WHERE 帖子在当前日期之前发布 - 1 天。

那么我怎么能在语句中做这样的循环呢?还是我应该保持这种状态?

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

还有更好的方法吗?

我看起来很愚蠢:p

提前致谢

编辑

对于未来的谷歌人。

我最终做了

$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 处理它。

4

2 回答 2

3

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

现在,我注意到你所拥有的一件事,不知道是不是故意的。但是由于您每次都重新查询确切的行集,但是对于不同的 <= 日期范围,您的所有计数都将是先前的增量。例如: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

如果您真正想要的是有多少实际帖子例如:从今天,就在一天前,就在两天前,就在三天前,您将不得不调整查询以将 <= 删除为仅“=”

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

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

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

总体而言,与每次处理每个字段的查询略有不同。此查询处理 1 条记录并考虑所有列结果值。只是您拥有的解决方案的另一种选择。我不知道对这么小的表的性能影响,但如果你有一个有 1000 条帖子活动的人,它可能会更可衡量。

于 2013-05-16T17:15:22.850 回答
2

You can simplify your sql and use this instead. 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. Now in your application login you just need to handle this data. This will simplify your sql and make it perform efficiently.

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

Hope this helps.

于 2013-05-16T11:25:52.010 回答