查询数据以创建统计图

时间:2019-07-23 02:18:06

标签: mysql

我有一张表,其中包含这些字段id,title,ddetail,date_created,type和website_id,称为Warning。我想要查询给定时间的数据,并且遇到以下情况(我的看法):

  • 如果月份和年份在开始时间,则结束时间相等,我将查询该月的每周警告。(例如,01/07/2019-31/07/2019)
  • 如果两者都在同一年,我将查询每月警告,这意味着我将计算从开始月份到结束月份的警告数量。 (例如1/2019-9/2019)
  • 最后一种情况与上述情况几乎相似,但时间间隔较长。 (例如,12/2018-3/2019)

上述情况的示例:

  • 时间:01/07/2019-31/07/2019,结果:

     01/07/2019 - 07/07/2019: 3 warnings
     08/07/2019 - 14/07/2019: 0 warning
     15/07/2019 - 21/07/2019: 1 warning
     22/07/2019 - 28/07/2019: 2 warning
     29/07/2019 - 31/07/2019: 0
    
  • 案例2,时间:1/019-6/2019

     1/2019: 1 warnings
     2/2019: 3 warnings
     3/2019: 0 warnings
     4/2019: 1 warnings
     5/2019: 2 warnings
     6/2019: 0 warnings
    

这是我的解决方案,但是我无法编写SQL查询。我需要3种情况下的3条SQL查询,并在可能的情况下解决问题。

1 个答案:

答案 0 :(得分:0)

首先,我们知道我们需要选择警告,然后按一定时间范围对它们进行分组。我将按日历周分组。

一个月内的所有警告:

SELECT `id` from warnings WHERE date_created >= 2019-07-01 AND date_created <= 2019-07-31;

要获得本月有多少警告,它几乎是相同的:

SELECT count(`id`) from warnings WHERE date_created >= 2019-07-01 AND date_created <= 2019-07-31;

这将返回其中包含单个值的一行。还不是很有趣。要了解每个(日历)周发生了多少次警告,可以按周将结果分组。

SELECT count(`id`) as num_warnings, WEEK(date_created) as weeknum
FROM warning
WHERE `date_created` >= 2019-07-01 AND date_created <= 2019-07-31
GROUP BY weeknum;

这将为您提供一周内的警告次数。如果该月从星期五开始,则第一周的数字会很少。

要查询从本月第一天开始的七天间隔,事情会变得复杂得多。 (此外,最后一个“周”显然不会整整7天。)

为了提供帮助,我首先提到SELECT / GROUP BY - segments of time (10 seconds, 30 seconds, etc),它讨论了以秒为单位的分组。一周是60 * 60 * 24 * 7秒,因此答案可以很容易地转换-但是我们有一个陷阱。

SELECT count(`id`) as num_warnings as weeknum
FROM warning
WHERE `date_created` >= 2019-07-01 AND date_created <= 2019-07-31
GROUP BY UNIX_TIMESTAMP(date_created) DIV 604800

这将警告的时间戳记除以一周中的秒数,然后将小数点除掉。因此,每604800秒,除法将增加1。差不多了,但这是个难题:这将告诉您自1973年1月1日以来已经有几周,您想知道自第一年以来有几周。这个月。换句话说,您希望月初(而不是1973年)为零。

SELECT count(`id`) as num_warnings
FROM warnings
WHERE `date_created` >= 2019-07-01 AND date_created <= 2019-07-31
GROUP BY (UNIX_TIMESTAMP(date_created) - UNIX_TIMESTAMP('2019-07-01')) DIV 604800

将一个月除以几周就差不多了。我对Django几乎一无所知,因此我无法为您提供生成查询的代码。

但是一年除以几个月呢?最初,这似乎是一个类似的问题,但有一个问题:一个月中有几秒钟?

一年中按月分组的答案实际上更像是上面针对周除的原始解决方案。之所以有效,是因为年份总是从一个月初开始:

SELECT count(`id`) as num_warnings, MONTH(date_created) as monthNum
FROM warnings
WHERE `date_created` >= 2019-01-01 AND date_created <= 2019-12-31
GROUP BY monthNum;

应该使您靠近要去的地方。

两个查询之间的差异足够大,您将希望在Django代码中识别出不同的情况并构建适当的查询。