我有一个具有以下结构(近似)的表rate
:
CREATE TABLE `rate` (
`id` int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
`from` date NOT NULL,
`to` date NOT NULL
)
和一个(大约)相同的表
stop_sale
:CREATE TABLE `stop_sale` (
`id` int(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
`from` date NOT NULL,
`to` date NOT NULL
)
考虑到每个时间间隔是它们各自的
from
和to
字段之间覆盖的天数范围:我想以时间间隔不重叠的方式一起查询这些表,而是调整以使
stop_sale
优先。例
rates
| id | from | to |
| 1 | "2018-01-05" | "2018-01-31" |
| 2 | "2018-02-01" | "2018-02-15" |
stop_sale
| id | from | to |
| 1 | "2018-01-11" | "2018-01-20" |
| 2 | "2018-02-01" | "2018-02-10" |
所需结果
| rate_id | from | to |
| 1 | "2018-01-05" | "2018-01-10" |
| 0 | "2018-01-11" | "2018-01-20" |
| 1 | "2018-01-21" | "2018-01-31" |
| 0 | "2018-02-01" | "2018-02-10" |
| 2 | "2018-02-11" | "2018-02-15" |
注意,带有
rate
的id=1
如何基于带有stop_rate
的id=1
的时间间隔分为两个记录(注意:id
并不重要,只是时间间隔)。换句话说,
stop_sale
时间间隔在rate
时间间隔上执行减法运算,并且还涂有最终结果集。SQL可能吗?和MySQL?
如果是这样,查询的最佳状态是什么?用PHP处理此操作是否更好?
最佳答案
据我所知,仅凭SQL查询是无法做到这一点的。可以在存储的函数中迭代解决此问题,但是没有干净的方法可以返回数据。最好是返回一个带分隔符的数据字符串。
一种替代方法是构建一个存储过程,该存储过程定期填充结果数据表,并对其进行php查询。基本逻辑是:
传递起始数据值-起始日期。
用查询创建一个临时表:
select * from rates
where from >= starting_date
union
select * from stop_sale
where from >= starting_date
order by from asc
遍历临时表。
获得第一个“来自”价值。
获得更大的“价值”价值
查找'from'值当前'from'值,但!='from'值已在正在填充的结果表中
如果找到,则将当前的“从”值和“至”值-1天插入到要填充的结果表中
否则将当前的“从”值和“到”值插入到要填充的结果表中
这种基本逻辑可以在php中完成,尽管它可能更复杂,因为您将需要构建一个从上述临时表查询返回的行的数组,在其上运行该逻辑,并构建一个结果数组。这将比运行存储过程效率低,因为一旦运行存储过程,您将只需要在比该运行过程更新的数据上再次运行该存储过程。因此,starting_data参数。
希望对您有帮助。
关于mysql - 用其他日期分割日期,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48117311/