如何使用MySQL查询一年中每月的记录数

 更新时间:2022年09月13日 08:52:04   作者:CHJH_MingYI  
这篇文章主要给大家介绍了关于如何使用MySQL查询一年中每月的记录数的相关资料,文中通过实例代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

以下演示将在下表数据中进行:

其中:id为主键用于表的连接;value1为需要统计的主体,如用户等;date为记录日期。

先说结论

SELECT
    tmp.value1 AS `value1`,
    MONTH(SUBSTRING_INDEX(tmp.ct, ',', 1)) AS `month`,
    LENGTH(tmp.ct) - LENGTH(
REPLACE
    (tmp.ct, ',', '')
) + 1 AS `cnt`
FROM
    (
    SELECT
        id,
        value1,
        GROUP_CONCAT(date_value) AS ct
    FROM
        test_year_record
    GROUP BY
        value1,
        INTERVAL(
            date_value,
            DATE(CONCAT('2022', '-01-01')),
            DATE(CONCAT('2022', '-02-01')),
            DATE(CONCAT('2022', '-03-01')),
            DATE(CONCAT('2022', '-04-01')),
            DATE(CONCAT('2022', '-05-01')),
            DATE(CONCAT('2022', '-06-01')),
            DATE(CONCAT('2022', '-07-01')),
            DATE(CONCAT('2022', '-08-01')),
            DATE(CONCAT('2022', '-09-01')),
            DATE(CONCAT('2022', '-10-01')),
            DATE(CONCAT('2022', '-11-01')),
            DATE(CONCAT('2022', '-12-01')),
            DATE(CONCAT('2023', '-01-01'))
        )
) AS tmp
JOIN test_year_record AS ot
ON
    ot.id = tmp.id
WHERE
    ot.value1 = 1 AND YEAR(SUBSTRING_INDEX(tmp.ct, ',', 1)) = '2022'

注:以’2022’为例,上面结论中使用了CONCAT方法进行字符串拼接,方便了年份替换,可以直接替换置对应的ORM的参数等。

查询结果

思路及SQL解释

这个问题可以划分为如下几个子问题,我们可以挨个分析解决:

1. 如何以月份划分

对于一个月份的数据可以如下判断:

date_value >= DATE_ADD(date_value, INTERVAL - DAY(date_value) + 1 DAY)
 AND
data_value <= LAST_DAY(data_value)

解释一下:

DATE_ADD(date_value, INTERVAL - DAY(date_value) + 1 DAY):data_value所在月的第一天,原理为在data_value的基础上加上-DAY(data_value)天数再+1,当然也可以使用DATE_SUB或者去YEAR和MONTH信息再进行拼接;

LAST_DAY(date_value):data_value所在月的最后一天。

一个月的解决了,那么多个月的无非就手写几个范围就可以了(x

当然不能手写这些范围,一方面是很麻烦而且不好看,另一方面是会给mysql带来过多的计算量。

那么如何给12月进行划分呢:

INTERVAL() 函数可以解决我们的问题:

INTERVAL( N , n 1 , n 2 , ⋯   , n 3 N,n_1,n_2,\cdots,n_3 N,n1​,n2​,⋯,n3​),其中 N N N为带判断是数据,后面的 n 1 ∼ n n n_1 \sim n_n n1​∼nn​分别为各个间断点,这个函数的返回值如下,当 N < n 1 N < n1 N<n1返回0,当 n 1 ≤ N < n 2 n_1 \leq N < n_2 n1​≤N<n2​时返回1,当 n 2 ≤ N < n 3 n_2 \leq N < n_3 n2​≤N<n3​时返回2,…,以此类推。

据此,我们可以给一年做一个分段:

 INTERVAL(
            date_value,
            DATE(CONCAT('2022', '-01-01')), # 一月
            DATE(CONCAT('2022', '-02-01')), # 二月
            DATE(CONCAT('2022', '-03-01')), # 三月
            DATE(CONCAT('2022', '-04-01')), # 四月
            DATE(CONCAT('2022', '-05-01')), # 五月
            DATE(CONCAT('2022', '-06-01')), # 六月
            DATE(CONCAT('2022', '-07-01')), # 七月
            DATE(CONCAT('2022', '-08-01')), # 八月
            DATE(CONCAT('2022', '-09-01')), # 九月
            DATE(CONCAT('2022', '-10-01')), # 十月
            DATE(CONCAT('2022', '-11-01')), # 十一月
            DATE(CONCAT('2022', '-12-01')), # 十二月
            DATE(CONCAT('2023', '-01-01')) # 次年一月,防止次年的数据记录进当年12月中
        )

注: 这里其实还有个问题,就是结果会返回去年的数据(0),可以像我一样在外查询里面进行一个年份判断,也可以交给java等检测。

2.获取每月数据

可以使用GROUP BY子句,以INTERVAL的值进行分组(为了保证属于同一个value1的数据,还需要以value1进行分组)。

注:GROUP BY 子句中含有多个参数时,将会是多条这些数据都一样的记录分为一组。

仅仅是做了分组是不够的,我们还需要GROUP_CONCAT()函数来获取一个分组中的数据集。

执行完当前这步,可以获取的结果如下:

3.统计每月数据

在ct这一列中,我们获取的数据是有规律的,比如一个日期中会有两个"-"、两个日期之间以",“分隔。

这里我们选择以”,"为标志,统计出有多少个分隔符,再+1就得到了数据的数量。

至于实现方式,可以使用如下方式:

LENGTH(tmp.ct) - LENGTH(REPLACE(tmp.ct, ',', '')) + 1

4.统计值与月份相对应

取得GROUP_CONCAT获取的第一个日期即可代表这一整个数据所在的月份。

可以使用SUBSTRING_INDEX()函数,它有三个参数,第一个参数为待片取的字符串、第二个参数为分隔符、第三个参数为第几个截取到第几个分隔符。

如此一来:

SUBSTRING_INDEX(tmp.ct, ',', 1)

便可以取到该日期,再使用MONTH函数即可获取对应的月份。

5.总体整合

我这里是使用了一次子查询,子查询获取对应的分组及GROUP_CONCAT数据,再交由外查询进行处理。

结语

这里给出的方案仅仅是一种方案,也许存在着其他更快更好的解决方案但我没有想到,在复杂问题面前一步一步获取小数据是我习惯,这也就使得很可能出现多个嵌套着的子查询。

到此这篇关于如何使用MySQL查询一年中每月的记录数的文章就介绍到这了,更多相关MySQL查询每月记录数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySql数据库基础之分组查询详解

    MySql数据库基础之分组查询详解

    这篇文章主要介绍了mysql按照时间分组查询的语句,非常实用,sql语句简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • 关于Mysql-connector-java驱动版本问题总结

    关于Mysql-connector-java驱动版本问题总结

    这篇文章主要介绍了Mysql-connector-java驱动版本问题,本文给大家介绍的很详细,通过原因说明问题小结个人建议给大家展示的很好,需要的朋友可以参考下
    2021-06-06
  • Mysql常用基准测试命令总结

    Mysql常用基准测试命令总结

    在本篇文章中我们给大家分享了关于Mysql常用基准测试命令的总结内容,有需要的读者们可以学习下。
    2018-10-10
  • MySQL 使用SQL语句修改表名的实现

    MySQL 使用SQL语句修改表名的实现

    这篇文章主要介绍了MySQL 使用SQL语句修改表名的实现操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • mysql 忘记密码的解决方法(linux和windows小结)

    mysql 忘记密码的解决方法(linux和windows小结)

    下面是linux和windows下mysql丢失密码的解决办法
    2008-12-12
  • mysql如何在存储过程中输出日志信息

    mysql如何在存储过程中输出日志信息

    这篇文章主要介绍了mysql如何在存储过程中输出日志信息问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Python版Mysql爆破小脚本

    Python版Mysql爆破小脚本

    本文给大家分享的是使用Python制作的MySQL在线用户密码的暴力破解脚本,非常的好用,有需要的小伙伴可以参考下
    2016-10-10
  • rpm -ivh方式安装mysql并修改数据存储位置的实现

    rpm -ivh方式安装mysql并修改数据存储位置的实现

    在Linux环境下进行MySQL的安装可以使用不同的方式,但在本文中我们将关注一种特定的方式,即通过RPM包的方式进行安装,本文主要介绍了rpm -ivh方式安装mysql并修改数据存储位置的实现,感兴趣的可以了解一下
    2023-09-09
  • 学习mysql 如何行转列与列传行

    学习mysql 如何行转列与列传行

    这篇文章主要介绍了mysql行转列与列传行的使用方法,帮助大家更好的理解和学习MySQL的使用,语句不难,但有一定的知识参考价值,需要的朋友可以参考一下,希望给你的学习带来帮助
    2022-02-02
  • MySQL5.7主从配置实例解析

    MySQL5.7主从配置实例解析

    这篇文章主要为大家详细解析了MySQL5.7主从配置的实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-03-03

最新评论