使用MySQL进行活动关联查询

使用MySQL进行活动关联查询,mysql,Mysql,问题: 我有两个实体foo和bar,我想将它们的活动关联起来。具体来说,我想确定哪些bar对象与给定的foo对象同时处于活动状态 为此,我建立了一个简单的MySQL数据库,其中包含两个表: select * from foo; +------+---------------------+---------------------+ | id | arrive | depart | +------+---------------------+

问题:

我有两个实体foo和bar,我想将它们的活动关联起来。具体来说,我想确定哪些bar对象与给定的foo对象同时处于活动状态

为此,我建立了一个简单的MySQL数据库,其中包含两个表:

select * from foo;
+------+---------------------+---------------------+
| id   | arrive              | depart              |
+------+---------------------+---------------------+
|    1 | 2014-10-01 08:00:00 | 2014-10-01 09:00:00 |
|    1 | 2014-10-01 10:00:00 | 2014-10-01 11:00:00 |
|    1 | 2014-10-01 12:00:00 | 2014-10-01 13:00:00 |
|    2 | 2014-10-01 09:00:00 | 2014-10-01 10:00:00 |
|    2 | 2014-10-01 12:00:00 | 2014-10-01 13:00:00 |
+------+---------------------+---------------------+

select * from bar;

+------+---------------------+---------------------+
| id   | start               | end                 |
+------+---------------------+---------------------+
|    1 | 2014-10-01 08:05:00 | 2014-10-01 08:55:00 |
|    1 | 2014-10-01 09:05:00 | 2014-10-01 09:55:00 |
|    1 | 2014-10-01 11:05:00 | 2014-10-01 11:55:00 |
|    2 | 2014-10-01 11:05:00 | 2014-10-01 11:55:00 |
|    2 | 2014-10-01 12:05:00 | 2014-10-01 12:55:00 |
|    2 | 2014-10-01 07:05:00 | 2014-10-01 07:55:00 |
|    3 | 2014-10-01 08:05:00 | 2014-10-01 08:55:00 |
|    3 | 2014-10-01 10:05:00 | 2014-10-01 10:55:00 |
|    3 | 2014-10-01 12:05:00 | 2014-10-01 12:55:00 |
+------+---------------------+---------------------+
不用说,到达和开始列表示活动周期的开始,离开和结束列表示每个周期的结束,id列是每个对象的唯一标识符

作为第一步,对于foo中的每个活动周期,我想确定在同一时间段内处于活动状态的bar对象集

根据上述foo 1的样本数据: 在8:00和9:00之间,即在foo 1的第一个活动期间,酒吧1和酒吧3都处于活动状态, 在10:00和11:00之间,只有第3栏处于活动状态, 在12:00和13:00之间,酒吧2和酒吧3都处于活动状态,以此类推

一旦确定了这些集合,如果我能确定它们的交点,我将得到我想要的答案,例如,条形图3是唯一一个在与foo对象1同时处于活动状态的条形图对象

我正在尝试开发一个将返回此结果的查询。理想情况下,此查询将遍历整个数据库,并在活动重合的位置吐出包含一个foo id和一个bar id的行

作为一个起点,我提出了一个查询,以识别在foo活动的每个阶段都处于活动状态的所有bar对象:

SELECT foo.id, 
       bar.id 
FROM foo 
LEFT JOIN bar 
ON bar.start >= foo.arrive 
AND bar.end <= foo.depart;
然而,我不知道从这里走到哪里。相关子查询似乎很有用,但我不太可能在没有错误的情况下构建一个相关子查询。我甚至不确定这是不是正确的方法


有什么建议吗?

据我所知,您的加入查询是正确的。它拾取完全包含在到达-离开间隔内的开始-结束间隔。加入是正确的选择

将invervals添加到结果集中可以更容易地解决这一问题:

SELECT foo.id AS fooid, arrive, depart,
       bar.id AS barid, start, end
  FROM foo 
  LEFT JOIN bar  
              ON bar.start >= foo.arrive 
             AND bar.end <= foo.depart
这里有一个SQL小提琴显示了这一点

然后,您要做的是计算您拥有的不同foo项的数量,并计算不同组合的数量。然后你把它们结合在一起,你就会得到你想要的结果


我想这正是你想要的。但是如果没有更全面的解释,就很难确定。

你能给我们一个例子,说明你想要的输出应该是什么样子吗?你的查询只考虑从一个foo的周期开始到结束的条形图。它们不能部分重叠吗?Arun我要寻找的输出只是foo ID和匹配的bar ID;奥利·琼斯的回答很准确@1010不,我特别想排除所有重叠的情况。我同意。我会交换连接和左连接,以包括没有条的foos。
SELECT a.fooid, b.barid
  FROM (
      SELECT COUNT(*) AS count,
             id AS fooid
        FROM foo
       GROUP BY id
        ) AS a
   JOIN (
       SELECT COUNT(*) AS count,
              foo.id AS fooid,
              bar.id AS barid
         FROM foo 
         LEFT JOIN bar  
                    ON bar.start >= foo.arrive 
                   AND bar.end <= foo.depart
        GROUP BY foo.id, bar.id
         ) AS b ON a.count=b.count AND a.fooid = b.fooid