mysql - 检索其存储的时间范围在给定工作日中出现一次或多次的行

标签 mysql innodb

我想知道从 MySQL 表中检索行的最佳方法(性能),其中两个日期类型字段一起组成给定的时间范围,恰好在相关时间范围内的某个工作日有某个日期.

假设给定的表结构和数据示例,检索其存储的时间范围恰好出现一次或多次星期一的所有行的最佳方式是什么,例如,星期一由数字 2 引用。

Table: ExampleA
Fields:
ID (int) | Begin (date) | End (date)
------------------------------------
1        |  2012-02-14  | 2012-02-16
2        |  2012-01-01  | 2012-01-15
3        |  2012-03-04  | 2012-03-06
4        |  2012-01-23  | 2012-02-07
5        |  2012-07-15  | 2012-07-15
6        |  2012-03-06  | 2012-03-13

在示例查询中,最好通过基于非零的索引引用给定的工作日,从周日开始到周六结束,组成以下索引位置:分别为 1 到 7。 (与 MySQL 函数 DAYOFWEEK 相同。)

更新:

一直在寻找一些关于如何在给定时间范围内逐日迭代的方法,但看起来不太好。创建临时表等的要求不切实际,当同时用户请求具有相同要求的操作时,会导致问题。

示例:How can I get a list of dates between two given dates with mysql?

最初的想法是循环遍历每一行时间范围内的每一天。然后,对于每个时间范围,逐日遍历初始日期到结束日期,并返回每个时间范围(行)找到的工作日列表。当然这不是一个快速的方法,但只是一个开始。还有比这个更好的推荐或其他建议吗?

更新2:

G-Nugget suggested创建七个 bool 字段,每个字段代表每个工作日,并且在添加新行时,将相应字段标记为 true,以表示在该行的时间范围内找到的工作日。当然,这是由使用数据库的应用程序完成的,而不是 SQL 查询本身。

这是我迄今为止所见过的最简单、对性能影响最小的解决方案,但是我无法编辑表架构。

更新3:

为了进一步澄清这个问题,以防有人感到困惑或误读。注:

I'm looking to retrieve the rows where you can find the week day Monday or another week day of my choosing somewhere in their time frame (going from "Being" to "End"), either at the "Begin", "End", or along the period of time ranging from "Begin" to "End"

更新4:

这里有一个SQL Fiddle这个问题供您尝试您的想法,而无需在您的计算机中构建表格。

更新 5 - 解决方案:

使用Alexey Gerasimov answer我能够将他的 where 子句逻辑应用于我自己的问题并解决我的解决方案。谢谢阿列克谢。

如果您阅读本文并想尝试一下,看看它是否适合您的需求:

您可以使用这个SQLFiddle或这个小查询来设置和运行他的解决方案:

# Create table
CREATE TABLE `ExampleA` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Begin` date NOT NULL,
  `End` date NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1;

# Insert demo data
INSERT INTO `ExampleA`(`ID`,`Begin`,`End`) VALUES  
(1,'2012-02-14','2012-02-16'),
(2,'2012-01-01','2012-01-15'),
(3,'2012-03-04','2012-03-06'),
(4,'2012-01-23','2012-02-07'),
(5,'2012-07-15','2012-07-15'),
(6,'2012-03-06','2012-03-13');

# Query to retrieve rows which time frame
# has one or more occurrences of a given weekday
#
# 1 Sunday
# 2 Monday
# 3 Tuesday
# 4 Wednesday
# 5 Thursday 
# 6 Friday
# 7 Saturday

SET @MYDAYOFWEEK=2;
SELECT * FROM ExampleA
WHERE
(
        ( @MYDAYOFWEEK >= DAYOFWEEK(BEGIN) AND @MYDAYOFWEEK <= DAYOFWEEK(BEGIN) + DATEDIFF(END,BEGIN) )
    OR  
        ( 
          @MYDAYOFWEEK+7 >= DAYOFWEEK(BEGIN) AND @MYDAYOFWEEK+7 <= DAYOFWEEK(BEGIN) + DATEDIFF(END,BEGIN) 
        )
)

最佳答案

像这样怎么样:

select * from ExampleA
where ID = MYDAYOFWEEK
and (
        ( id >= dayofweek(begin) and id <= dayofweek(begin) + DATEDIFF(end,begin) )
    OR  
        ( 
        id+7 >= dayofweek(begin) and id+7 <= dayofweek(begin) + DATEDIFF(end,begin) 
        )
    )   

第一个检查匹配同一周的日期,第二个检查跨越几周。但不确定这是否是性能最佳的查询

更新

抱歉。我认为第一列是一周的日期。要修复此问题,只需更改查询如下:

select * from ExampleA
where (
        ( MYDAYOFWEEK >= dayofweek(begin) and MYDAYOFWEEK <= dayofweek(begin) + DATEDIFF(end,begin) )
    OR  
        ( 
        MYDAYOFWEEK+7 >= dayofweek(begin) and MYDAYOFWEEK+7 <= dayofweek(begin) + DATEDIFF(end,begin) 
        )
    )  

这绝对不是很快

关于mysql - 检索其存储的时间范围在给定工作日中出现一次或多次的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14282694/

相关文章:

mysql - 哪些命令将使用 Powershell 中的现有 .sql 文件填充数据库

mysql - SQL:加入多个表

php - org.json.JSONException : Value <br of type java. lang.String 无法转换为 JSONObject

mysql - 是否有任何信息表/矩阵显示 char、varchar、text、real、double、float、binary、set、int、integer、longtext 的属性?

mysql - select count 只显示 1 个结果且有错误

mysql - 是否有可能获得 InnoDB 内部行 ID?

mysql - 选择查询锁定innodb表

php - 这两个表应该相关吗?

mysql - 如何调优MySQL的存储引擎

mysql - 我的 sql 第 12 行或“order ON order-user_id = user.id”附近出现错误。有什么想法吗?谢谢