显示所有周/月包括空计数

时间:2014-05-03 05:35:02

标签: php mysql

我想列出每周用户登录的次数。但是当一周没有任何用户登录时,这一周就不会显示出来。

我的查询如下:

SELECT *, 
  YEARWEEK(`date`) AS yw, 
  COUNT(`userid`) AS numaction 
FROM `login` 
WHERE `action` = 'login' AND `userid` != 'admin' 
GROUP BY week(`date`) 
ORDER BY `date` DESC;

我也在SO中看到了一些例子,但需要另一个周数字表。是否可以不使用周数表?

对于每月,是否一样?我的意思是没有月份表,只需使用表中的date

我做了sqlfiddle

3 个答案:

答案 0 :(得分:1)

我也使用虚拟表,我只是以不同的方式生成它。我有一张桌子'整体'它有一列(id),从1 ... 499开始有500行。这可用于生成任何日期范围。我们在这里使用几天。

已修复 - 忘记'或操作为空'测试。

SELECT *, 
  YEARWEEK(`the_day`) AS yw,
  COUNT(`userid`) AS numaction 
FROM 
    (SELECT
       MAKEDATE('2014', id) AS the_day
    FROM integerseries
    LIMIT 365) AS all_days
 LEFT JOIN `login` 
    ON DATE(login.`date`) = all_days.the_day 
WHERE `action` = 'login' AND `userid` != 'admin'   
  or `action` is null
GROUP BY WEEK(`the_day`)
ORDER BY `the_day` DESC;

答案 1 :(得分:0)

我最近问了一个similar question,并建议使用这样的“虚拟”表:

SELECT *
FROM
 (SELECT 0 AS w
   UNION ALL SELECT 1
   UNION ALL SELECT 2
   UNION ALL SELECT 3
   ... and so on...
   UNION ALL SELECT 53) AS weeks
LEFT JOIN login
ON WEEK(login.date) = weeks.w

这看起来很傻,但似乎是mysql的唯一方法。当然,UNION部分可以在php中轻松实现自动化。

要解决该评论,以下内容可能有效:

SELECT *
FROM
 (SELECT 0 AS w
   UNION ALL SELECT 1
   UNION ALL SELECT 2
   UNION ALL SELECT 3
   ...etc...
   UNION ALL SELECT 29
   UNION ALL SELECT 30
   UNION ALL SELECT 31
  ) AS days
LEFT JOIN login
ON DAY(login.date) = days.w 
WHERE days.w <= DAY(LAST_DAY(NOW()))

但在应用程序级别处理这样的事情真的更好。

答案 2 :(得分:0)

我最近遇到过类似的困境。这是愚蠢的,可能需要比其他解决方案更多的时间和更多的代码,但这里有我的提示:

  • 扫描表格中有几天/几周的活动

    $active=array();
    $sql=mysql_query("SELECT date FROM table GROUP BY date");
    while ($p=mysql_fetch_array($sql)) array_push($active,dateformat($p[date]));
    

    当然,您必须修改查询以满足您的日期格式要求

  • 使用基于时间戳的for循环显示数据

    for ($i=$tstamp_start;$i<=$tstamp_end;$i+=$diff)
      {
         $datefor=dateformat($i);
         if (in_array($datefor,$active))
          {
            $sql=mysql_query("SELECT ... WHERE date=$datefor GROUP BY date");
            //do whatever you want with the data
          }
         else
          {
            //display info about no activity that day/week/month
          }
      }
    

    对于$tstamp_start$tstamp_end,您可以查询SELECT min(date),max(date) ...,这样可以获得一行,其中包含两个可以追加到变量的元素

  • 我使用虚构函数dateformat(),我不知道如何在数据库中存储日期信息 - 您必须创建它以便能够获取数据for loop。

  • $diff变量存储时间戳差异以跳过天/周

我知道它很复杂但对我有用,我希望你能从中受益。