MySQL中根据日期进行范围查询

Posted weixin_43882265

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL中根据日期进行范围查询相关的知识,希望对你有一定的参考价值。

1.mysql中查询某年某月的数据

测试数据如下;

 

1.1查询2018年的数据:

select * from day_rate where year(date)='2018'


 

1.2查询2月份的数据:

select * from day_rate where month(date)='02'


 

1.3查询2019年2月份的数据:

select * from day_rate where year(date)='2019' and month(date)='02'


 

1.4查询年初第32天的数据:

select * from day_rate where dayofyear(date)='32'

MySQL中查询某年某月的数据

 

2.日期进行范围查询时不能超出某月的最大日期

好像是mysql8,使用between…and…查询时,当查询的右边界为2021-2-31时,超出了实际范围(因为2月不可能有31天),所以无法进行查询。

例如:

select * from t_ordersetting where orderDate between '2021-09-01' and '2021-09-31';

这个方法不行,因为9月没有31号,超出了9月的最大日期,所以查询错误。
 
解决方法:
方法一(已经过验证,可行):
使用 select * from t_ordersetting where year(orderDate)=#year and month(orderDate)=#month; 查询某年某月的数据,如下:

<select id="getOrderSettingByMonth" parameterType="map" resultType="com.itheima.pojo.OrderSetting">
        select * from t_ordersetting where year(orderDate)=#year and month(orderDate)=#month;
    </select>

方法二(查看评论得知,没验证,不知是否可行):
使用:SELECT * FROM t_ordersetting WHERE orderDate BETWEEN STR_TO_DATE('2021-04-1','%Y-%m-%d') AND STR_TO_DATE('2021-04-31','%Y-%m-%d')

MYsql 8数据库select * from t_ordersetting where orderDate between ‘2020-2-1‘ and ‘2020-2-31‘语句竟然不能用

PHP/MySQL:对数据库中的重复事件进行建模,但查询日期范围

【中文标题】PHP/MySQL:对数据库中的重复事件进行建模,但查询日期范围【英文标题】:PHP/MySQL: Model repeating events in a database but query for date ranges 【发布时间】:2012-11-27 22:29:12 【问题描述】:

我正在开发一个(我打算成为的)简单的 PHP/MySQL 应用程序。作为其中的一部分,我希望能够对重复事件进行建模,但是我需要能够查询两个日期之间发生的所有事件(包括重复事件)。这些事件只有一个日期,一天中的时间无关紧要。

我一直在研究这个问题,并研究了各种方法,包括 Calendar Recurring/Repeating Events - Best Storage Method 和 Repeating calendar events and some final maths。

但是,我在网上找到的任何支持这一点的数据库模式示例似乎只支持查询某一天发生的事件。不支持在某个日期范围内发生的事件。

作为一个抽象的例子

事件表(带有某种重复表示):

Event   | Start Date   |   Repeats
-------------------------------------
Meeting | 10/Dec/2012  |   Every 7 days
Lunch   | 10/Dec/2012  |   Every 1 days

目标抽象查询结果SELECT Events BETWEEN 09/Dec/2012 AND 20/Dec/2012

Event   |  Date        |   Repeats
-------------------------------------
Meeting | 10/Dec/2012  |   Every 7 days
Meeting | 17/Dec/2012  |   Every 7 days
Lunch   | 10/Dec/2012  |   Every 1 days
Lunch   | 11/Dec/2012  |   Every 1 days
Lunch   | 12/Dec/2012  |   Every 1 days
Lunch   | 13/Dec/2012  |   Every 1 days
etc...
Lunch   | 20/Dec/2012  |   Every 1 days

是否有支持此类查询的数据库架构?对于两天之间发生的任何事件(包括重复事件),我将如何在该架构上进行查询?

或者也许是用于重复事件的设计模式?

【问题讨论】:

这非常困难,并且可能以非常复杂的模式和/或查询告终。在 PHP 中通过对事件表的简单查询来构造结果集不是更容易(也更有效)吗? 也许,但我担心随着时间的推移,您可能会遇到一个结果集充满陈旧重复(或在您的日期范围内未出现的重复)并且必须修剪这些的潜在问题退出应用程序。 【参考方案1】:

我不太了解您的目标...也许您正在寻找 SQL 中的 UNIQUE 函数?

【讨论】:

可能不仅我误解了一些问题,而且我也无法预测我能获得的选票。猜猜,除非你知道确切的答案,否则最好不要写任何东西,否则要求更多信息或建议一些东西会让你被否决:))) 没错,您可以删除此答案以防止更多的反对意见【参考方案2】:

我将创建一个只有一个名为 id 的列的计数表,并用从 0 到 500 的数字填充该表。现在我们可以轻松地使用它来进行选择,而不是使用 while 循环。

Id
-------------------------------------
0
1
2
etc...

然后我会将事件存储在一个带有Name as varcharstartdate as datetimerepeats as int 的表中

Name    | StartDate            |   Repeats
-------------------------------------
Meeting | 2012-12-10 00:00:00  |   7
Lunch   | 2012-12-10 00:00:00  |   1

现在我们可以使用计数表来选择两个日期之间的所有日期:

SELECT DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY) as showdate
FROM `tally`
WHERE (DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY)<='2012-12-20 00:00:00')
ORDER BY Id ASC
ShowDate
-------------------------------------
2012-12-09 00:00:00
2012-12-10 00:00:00
2012-12-11 00:00:00
2012-12-12 00:00:00
2012-12-13 00:00:00
2012-12-14 00:00:00
2012-12-15 00:00:00
2012-12-16 00:00:00
2012-12-17 00:00:00
2012-12-18 00:00:00
2012-12-19 00:00:00
2012-12-20 00:00:00

然后我们将其加入事件表中以计算开始日期和演出日期之间的差异。我们将结果除以repeats 列,如果余数为0,则匹配。

所有组合变成:

SELECT E.Id, E.Name, E.StartDate, E.Repeats, A.ShowDate, DATEDIFF(E.StartDate, A.ShowDate) AS diff
FROM events AS E, (
    SELECT DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY) as showdate
    FROM `tally`
    WHERE (DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY)<='2012-12-20 00:00:00')
    ORDER BY Id ASC
) a
WHERE MOD(DATEDIFF(E.StartDate, A.ShowDate), E.Repeats)=0
AND A.ShowDate>=E.StartDate

这会导致

Id  | Name       |StartDate             | Repeats   | ShowDate              | diff
---------------------------------------------------------------------------------
1   | Meeting    | 2012-12-10 00:00:00  | 7         | 2012-12-10 00:00:00   | 0
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-10 00:00:00   | 0
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-11 00:00:00   | -1
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-12 00:00:00   | -2
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-13 00:00:00   | -3
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-14 00:00:00   | -4
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-15 00:00:00   | -5
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-16 00:00:00   | -6
1   | Meeting    | 2012-12-10 00:00:00  | 7         | 2012-12-17 00:00:00   | -7
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-17 00:00:00   | -7
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-18 00:00:00   | -8
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-19 00:00:00   | -9
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-20 00:00:00   | -10

现在您可以(而且应该!)加快速度。例如,通过直接将日期存储在表格中,您可以直接选择所有日期,而不是使用带有 dateadd 的计数表。您可以缓存并且不必再次计算的所有内容都是好的。

【讨论】:

以上是关于MySQL中根据日期进行范围查询的主要内容,如果未能解决你的问题,请参考以下文章

PHP/MySQL:对数据库中的重复事件进行建模,但查询日期范围

mysql 日期时间查询

mysql 如何实现Oracle中的这种日期查询?

如何根据日期选择 2 年时间范围 - MySQL?

如何使用查询在 mysql 数据库中插入日期范围?

这些查询 MySQL 日期范围之间有啥区别