【问题标题】:Show all dates between, even if no result显示之间的所有日期,即使没有结果
【发布时间】:2012-11-25 03:07:38
【问题描述】:
SELECT User_JoinDate, 
COUNT(User_ID) 
FROM Users WHERE `User_JoinDate` 
BETWEEN '2012-11-22' AND '2012-12-06' 
GROUP BY User_JoinDate 
ORDER BY User_JoinDate ASC"

我正在生成要在折线图中显示的数据。不幸的是,我不知道如何让上述查询显示 0 为没有用户可能已注册的日期。所以目前我的输出可能是这样的:

2012-11-22 - 2 2012-11-25 - 4

但我想要的是

2012-11-22 - 2 2012-11-23 - 0 2012-11-24 - 0 2012-11-25 - 4

我目前确实有一个工作版本,它将 MySQL 结果存储到一个数组中,然后 PHP 循环遍历并填充空白。这看起来很混乱,我希望通过 MySQL 有一个解决方案。我对该网站进行了很好的搜索,但很难理解其中的一些实现。有什么建议?

【问题讨论】:

  • 作为开始,我将创建一个查询,为您提供所有日期(我不确定如何,但我确定它在那里),然后与该表进行连接。跨度>

标签: mysql count group-by


【解决方案1】:

显示 66 条记录,但我已超过 120 条限制

SELECT AllDaysYouWant.MyJoinDate, count( U.id ) AS NumberJoined FROM (SELECT @curDate := Date_Add( @curDate , INTERVAL 1 DAY ) AS MyJoinDate FROM (SELECT @curDate := '2013-08-03')sqlvars, ipro_user LIMIT 150)AllDaysYouWant LEFT JOIN ipro_user U ON AllDaysYouWant.MyJoinDate = date_format( `date` , '%Y-%m-%d' ) AND U.active=1 GROUP BY AllDaysYouWant.MyJoinDate

查询没有错误,工作正常

【讨论】:

    【解决方案2】:

    您可以使用 MySQL 变量为您想要的所有日期构建一个自动结果集。

    select
          AllDaysYouWant.MyJoinDate,
          count( U.User_ID ) as NumberJoined
       from
          ( select
                  @curDate := Date_Add(@curDate, interval 1 day) as MyJoinDate
               from
                  ( select @curDate := '2012-11-21' ) sqlvars,
                  Users
               limit 18 ) AllDaysYouWant
          LEFT JOIN Users U
             on AllDaysYouWant.MyJoinDate = U.User_JoinDate
       group by
          AllDaysYouWant.MyJoinDate
    

    内部查询,我只是在没有键的情况下加入 users 表,所以它只是用来循环 X 条记录以表示您想要的日期跨度......这可能是 30、100 等等...... .. 只要表(在本例中为用户)具有您期望的尽可能多的记录。

    那么,只有天数的结果被加入到用户表中,但这一次是基于用户的 JOIN_DATE。简单的 COUNT() 应该可以得到你想要的。

    “AllDaysYouWant”是分配给内部第一部分查询的别名

      ( select
              @curDate := Date_Add(@curDate, interval 1 day) as MyJoinDate
           from
              ( select @curDate := '2012-11-21' ) sqlvars,
              Users
           limit 18 ) AllDaysYouWant
    

    这基本上说明...从用户表(但可以是任何),给我 18 行数据(通过限制,但几乎可以是任意数量的记录,但您只需要从 11 月 22 日到 12 月 6 日,这只有 14 天,但我做了 18 天,原则上它几乎可以是任何东西。用户表上方是 (select @curDate := '2012-11-21') sqlvars。查询中包含的任何选择语句作为表源的括号必须有一个别名,因为它只是一个我将使用的变量,所以不管它的名字是什么。所以,这个查询在 11 月 21 日开始变量,并且 Select @curDate := Date_Add ...blah blah 声明取@curDate 的当前值,向其添加 1 天(现在变为 11 月 22 日)并将其存储在返回的行“MyJoinDate”中。所以现在,这个内部查询创建了你的日期表从 11 月 22 日起向前 18 天的数据,并具有别名“AllDaysYouWant”供查询的其余部分参考。

    我已将您可能遇到的查询调整为 alias.field all 以进行澄清...

    【讨论】:

    • 感谢您的回复。不幸的是,我在 '1, @curDate) 作为 MyJoinDate FROM ( SELECT @curDate := '2' ) 附近遇到了 MySQL 语法错误。
    • @user1883978,已修复... SQL-Server 与 MySQL 的日期计算...查看修订后的 date_add() 内容
    • 当涉及到像这样的更复杂的查询时,这可能是我完全缺乏知识,但我似乎无法让它工作。我不确定“AllDaysYouWant”是什么,如果我尝试按原样使用查询,这将作为“未知列”失败。感谢您的帮助!
    • @user1883978,用别名字段引用修改查询并澄清“AllDaysYouWant”的内部查询
    • 正确,非常感谢您的帮助和对其工作原理的解释。
    【解决方案3】:

    你需要做什么
    1. 生成日期范围。
    2. 然后选择上面生成的查询中不存在的那些日期
    3. 并与上面的查询进行联合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-01
      • 2021-02-25
      • 1970-01-01
      • 1970-01-01
      • 2021-04-23
      • 1970-01-01
      • 2021-08-26
      • 1970-01-01
      相关资源
      最近更新 更多