草庐IT

MySQL找到重叠的交集

coder 2023-10-26 原文

我有一个包含事件的数据库表:

CREATE TABLE events
event VARCHAR(32)
,down_time TIMESTAMP
,up_time TIMESTAMP
,id INT UNSIGNED NOT NULL AUTO_INCREMENT KEY
,INDEX(event(16))
);

INSERT INTO events(event, down_time, up_time) VALUES
('e1', '2015-01-01 00:00:04', '2015-01-01 00:00:08'),
('e2', '2015-01-01 00:00:05', '2015-01-01 00:00:06'),
('e3', '2015-01-01 00:00:02', '2015-01-01 00:00:09'),
('e4', '2015-01-01 00:00:01', '2015-01-01 00:00:07'),
('e5', '2015-01-01 00:00:03', '2015-01-01 00:00:10');

SELECT * FROM events;

+-------+---------------------+---------------------+----+
| event | down_time           | up_time             | id |
+-------+---------------------+---------------------+----+
| e1    | 2015-01-01 00:00:04 | 2015-01-01 00:00:08 |  1 |
| e2    | 2015-01-01 00:00:05 | 2015-01-01 00:00:06 |  2 |
| e3    | 2015-01-01 00:00:02 | 2015-01-01 00:00:09 |  3 |
| e4    | 2015-01-01 00:00:01 | 2015-01-01 00:00:07 |  4 |
| e5    | 2015-01-01 00:00:03 | 2015-01-01 00:00:10 |  5 |
+-------+---------------------+---------------------+----+
5 rows in set (0.00 sec)

    1   2   3   4   5   6   7   8   9   10
    |   |   |   |   |   |   |   |   |   |
    |   |   |   |-------e1------|   |   |
    |   |   |   |   |-e2|   |   |   |   |
    |   |--------------e3-----------|   |
    |----------e4-----------|   |   |   |
    |   |   |-------------e5------------|

我想确定所有事件是否在任一时间重叠。 所以在上面它们都在这里相交(e2):

Overlap |overlap_down_time   | overlap_up_time     | overlap_duration
1       |2015-01-01 00:00:05 | 2015-01-01 00:00:06 | 00:00:01

我可以使用此查询找到事件对之间的重叠,但不确定如何包含所有事件..非常感谢!

SELECT
  e1.event AS event1_name,
  e1.down_time AS event1_down_time,
  e1.up_time AS event1_up_time,
  TIMEDIFF(e1.up_time, e1.down_time) AS event1_duration,

  e2.event AS event2_name,
  e2.down_time AS event2_down_time,
  e2.up_time AS event2_up_time,
  TIMEDIFF(e2.up_time, e2.down_time) AS event1_duration,

  GREATEST(e1.down_time,e2.down_time) AS overlap_down_time, 
  LEAST(e1.up_time,e2.up_time) AS overlap_up_time,
  TIMEDIFF( LEAST(e1.up_time,e2.up_time),
  GREATEST(e1.down_time,e2.down_time) ) AS overlap_duration

 FROM events e1

INNER JOIN events e2 ON e1.id < e2.id
WHERE
 ( e2.down_time <= e1.up_time ) 
AND
 ( e2.up_time >= e1.down_time );

下面提出的解决方案似乎没有涵盖事件在整个时间范围内发生两次的情况......如下面的 e2 所发生的那样:

1   2   3   4   5   6   7   8   9   10
|   |   |   |-------e1------|   |   |
|   |   |---e2--|   |-------e2------|   
|   |-------------e3------------|   |
|----------e4-----------|   |   |   |

INSERT INTO events(event, down_time, up_time) VALUES
    ('e1', '2015-01-01 00:00:04', '2015-01-01 00:00:08'),
    ('e2', '2015-01-01 00:00:03', '2015-01-01 00:00:05'),
    ('e2', '2015-01-01 00:00:06', '2015-01-01 00:00:10'),
    ('e3', '2015-01-01 00:00:02', '2015-01-01 00:00:09'),
    ('e4', '2015-01-01 00:00:01', '2015-01-01 00:00:07');

我已经能够通过使用两阶段查询来识别相交:

CREATE VIEW overlap1 AS
SELECT
CONCAT(a.event,'-', b.event) overlaps,
GREATEST(a.down_time,b.down_time) AS downtime, 
LEAST(a.up_time,b.up_time) AS uptime,
TIME_TO_SEC(TIMEDIFF( LEAST(a.up_time,b.up_time),
    GREATEST(a.down_time,b.down_time))) AS duration

FROM events a 
JOIN events b 
ON  a.event < b.event 
    AND (a.event = 'e1' OR a.event = 'e2' OR a.event = 'e3' OR a.event = 'e4')
    AND (b.event = 'e1' OR b.event = 'e2' OR b.event = 'e3' OR b.event = 'e4') 
WHERE   ( a.down_time <= b.up_time )
AND     ( a.up_time >= b.down_time );

SELECT * FROM overlap1;
+----------+---------------------+---------------------+----------+
| overlaps | downtime            | uptime              | duration |
+----------+---------------------+---------------------+----------+
| e1-e2    | 2015-01-01 00:00:04 | 2015-01-01 00:00:05 |        1 |
| e1-e2    | 2015-01-01 00:00:06 | 2015-01-01 00:00:08 |        2 |
| e1-e3    | 2015-01-01 00:00:04 | 2015-01-01 00:00:08 |        4 |
| e2-e3    | 2015-01-01 00:00:03 | 2015-01-01 00:00:05 |        2 |
| e2-e3    | 2015-01-01 00:00:06 | 2015-01-01 00:00:09 |        3 |
| e1-e4    | 2015-01-01 00:00:04 | 2015-01-01 00:00:07 |        3 |
| e2-e4    | 2015-01-01 00:00:03 | 2015-01-01 00:00:05 |        2 |
| e2-e4    | 2015-01-01 00:00:06 | 2015-01-01 00:00:07 |        1 |
| e3-e4    | 2015-01-01 00:00:02 | 2015-01-01 00:00:07 |        5 |
+----------+---------------------+---------------------+----------+

CREATE VIEW overlap2 AS
SELECT
CONCAT(a.overlaps,'-',b.overlaps) AS overlaps,
GREATEST(a.downtime,b.downtime) AS downtime,
LEAST(a.uptime,b.uptime) AS uptime,
TIMEDIFF( LEAST(a.uptime,b.uptime),
GREATEST(a.downtime,b.downtime) ) AS duration

FROM overlap1 a
JOIN overlap1 b 
ON a.overlaps < b.overlaps
AND (a.overlaps = 'e1-e2' OR a.overlaps = 'e3-e4')
AND (b.overlaps = 'e1-e2' OR b.overlaps = 'e3-e4')

WHERE   ( a.downtime <= b.uptime )
AND ( a.uptime >= b.downtime );

SELECT * FROM overlap2;
+-------------+---------------------+---------------------+----------+
| overlaps    | downtime            | uptime              | duration |
+-------------+---------------------+---------------------+----------+
| e1-e2-e3-e4 | 2015-01-01 00:00:04 | 2015-01-01 00:00:05 | 00:00:01 |
| e1-e2-e3-e4 | 2015-01-01 00:00:06 | 2015-01-01 00:00:07 | 00:00:01 |
+-------------+---------------------+---------------------+----------+

如果可能的话,我想通过一个查询来实现这一点..感谢任何帮助!

最佳答案

以下查询将满足您的要求:

select e1.* from events e1
join events e2 on e1.down_time>=e2.down_time and e1.up_time<=e2.up_time
group by e1.event
having count(*)=(select count(*) from events)

http://sqlfiddle.com/#!9/7c733/4 验证结果

关于MySQL找到重叠的交集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32789962/

有关MySQL找到重叠的交集的更多相关文章

  1. ruby-on-rails - capybara ::ElementNotFound:无法找到 xpath "/html" - 2

    我正在学习http://ruby.railstutorial.org/chapters/static-pages上的RubyonRails教程并遇到以下错误StaticPagesHomepageshouldhavethecontent'SampleApp'Failure/Error:page.shouldhave_content('SampleApp')Capybara::ElementNotFound:Unabletofindxpath"/html"#(eval):2:in`text'#./spec/requests/static_pages_spec.rb:7:in`(root)'

  2. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  3. ruby - 如何找到调用当前方法的方法 - 2

    如何找到调用此方法的位置?defto_xml(options={})binding.pryoptions=options.to_hifoptions&&options.respond_to?(:to_h)serializable_hash(options).to_xml(options)end 最佳答案 键入caller。这将返回当前调用堆栈。文档:Kernel#caller.例子[0]%rspecspec10/16|===================================================62=====

  4. ruby-on-rails - 无法安装 mysql2 0.3.14 gem - 2

    我看到其他人也遇到过类似的问题,但没有一个解决方案对我有用。0.3.14gem与其他gem文件一起存在。我已经完全按照此处指示完成了所有操作:https://github.com/brianmario/mysql2.我仍然得到以下信息。我不知道为什么安装程序指示它找不到include目录,因为我已经检查过它存在。thread.h文件存在,但不在ruby​​目录中。相反,它在这里:C:\RailsInstaller\DevKit\lib\perl5\5.8\msys\CORE\我正在运行Windows7并尝试在Aptana3中构建我的Rails项目。我的Ruby是1.9.3。$gemin

  5. ruby - 查找重叠的正则表达式匹配项 - 2

    我想找到给定字符串中的所有匹配项,包括重叠匹配项。我怎样才能实现它?#Example"a-b-c-d".???(/\w-\w/)#=>["a-b","b-c","c-d"]expected#Solutionwithoutoverlappedresults"a-b-c-d".scan(/\w-\w/)#=>["a-b","c-d"],but"b-c"ismissing 最佳答案 在积极的前瞻中使用捕获:"a-b-c-d".scan(/(?=(\w-\w))/).flatten#=>["a-b","b-c","c-d"]参见Rubyde

  6. ruby - 确定字符串的结尾是否与单独的字符串的开头重叠 - 2

    我想查找字符串的结尾是否与单独字符串的开头重叠。例如,如果我有这两个字符串:string_1='Peoplesaynothingisimpossible,butI'string_2='butIdonothingeveryday.'如何找到string_1末尾的“butI”部分与string_2开头相同?我可以编写一个方法来遍历这两个字符串,但我希望得到一个包含我错过的Ruby字符串方法或Ruby习惯用法的答案。 最佳答案 将MARKER设置为一些从未出现在您的string_1和string_2中的字符串。有一些方法可以动态地做到这一

  7. python - 帮我找到合适的 ruby​​/python 解析器生成器 - 2

    我使用的第一个解析器生成器是Parse::RecDescent,它的指南/教程很棒,但它最有用的功能是它的调试工具,特别是tracing功能(通过将$RD_TRACE设置为1来激活)。我正在寻找可以帮助您调试其规则的解析器生成器。问题是,它必须用python或ruby​​编写,并且具有详细模式/跟踪模式或非常有用的调试技术。有人知道这样的解析器生成器吗?编辑:当我说调试时,我并不是指调试python或ruby​​。我指的是调试解析器生成器,查看它在每一步都在做什么,查看它正在读取的每个字符,它试图匹配的规则。希望你明白这一点。赏金编辑:要赢得赏金,请展示一个解析器生成器框架,并说明它的

  8. ruby - 如何使用 ruby​​ mysql2 执行事务 - 2

    我已经开始使用mysql2gem。我试图弄清楚一些基本的事情——其中之一是如何明确地执行事务(对于批处理操作,比如多个INSERT/UPDATE查询)。在旧的ruby-mysql中,这是我的方法:client=Mysql.real_connect(...)inserts=["INSERTINTO...","UPDATE..WHEREid=..",#etc]client.autocommit(false)inserts.eachdo|ins|beginclient.query(ins)rescue#handleerrorsorabortentirelyendendclient.commi

  9. ruby - 404 未找到,但可以从网络浏览器正常访问 - 2

    我在这方面尝试了很多URL,在我遇到这个特定的之前,它们似乎都很好:require'rubygems'require'nokogiri'require'open-uri'doc=Nokogiri::HTML(open("http://www.moxyst.com/fashion/men-clothing/underwear.html"))putsdoc这是结果:/Users/macbookair/.rvm/rubies/ruby-2.0.0-p481/lib/ruby/2.0.0/open-uri.rb:353:in`open_http':404NotFound(OpenURI::HT

  10. ruby-on-rails - 通过 has_many 找到 Rails :through - 2

    我正在寻找一种方法来通过关联查询基于has_many中的子项的模型。我有3个模型:classConversation我需要找到参与者匹配一组ID的对话。这是我目前拥有的(不工作):Conversation.includes(:participants).where(participants:params[:participants]) 最佳答案 听起来你只是想要对话,如果是这样你可以加入。Conversation.joins(:participants).where(:users=>{:id=>params[:participant

随机推荐