MySQL公式确定最大并发事件数

时间:2013-10-22 15:42:20

标签: mysql

我正试图想办法在MySQL表中输入两个字段条目(一个是时间戳,例如'2013-07-31 11:59:46',另一个是持续时间,以秒为单位例如,'55'并找到彼此重叠的所有记录以及在这段时间内有多少重叠的记录。我已经头痛但我确定它可以以某种方式完成?什么是一个好方法得到返回值?

例如,假设从1月1日起我总共有5个参赛作品

2013-01-01 09:00:00 | 30     (an event that started at 9:00am and lasted 30 seconds)
2013-01-01 09:02:00 | 360    (an event that started at 9:02am and lasted 6 minutes)
2013-01-01 09:03:00 | 600    (an event that started at 9:03am and lasted 10 minutes)
2013-01-01 09:11:00 | 10    (an event that started at 9:11am and lasted 10 seconds)
2013-01-01 09:12:00 | 30    (an event that started at 9:12am and lasted 30 seconds)

针对这些条目运行我会得到一个返回值“2”,因为这是最大并发事件数。 (事件#2和#3重叠。然后,事件#2在事件#3和#4开始之前结束,这反过来重叠。这不会改变我们的返回值,因为在任何给定时间仍然只有两个并发事件。)

1 个答案:

答案 0 :(得分:0)

考虑以下内容......

 DROP TABLE IF EXISTS my_table;

 CREATE TABLE my_table
 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
 ,dt DATETIME NOT NULL
 ,duration INT NOT NULL
 );

 INSERT INTO my_table (dt,duration) VALUES
 ('2013-01-01 09:00:00',30),
 ('2013-01-01 09:02:00',360),
 ('2013-01-01 09:03:00',600),
 ('2013-01-01 09:11:00',10),
 ('2013-01-01 09:12:00',30);


  SELECT *
    FROM my_table x
    JOIN my_table y
      ON y.id <> x.id
     AND y.dt < (x.dt + INTERVAL x.duration SECOND)
     AND (y.dt + INTERVAL y.duration SECOND) > x.dt;
 +----+---------------------+----------+----+---------------------+----------+
 | id | dt                  | duration | id | dt                  | duration |
 +----+---------------------+----------+----+---------------------+----------+
 |  3 | 2013-01-01 09:03:00 |      600 |  2 | 2013-01-01 09:02:00 |      360 |
 |  2 | 2013-01-01 09:02:00 |      360 |  3 | 2013-01-01 09:03:00 |      600 |
 |  4 | 2013-01-01 09:11:00 |       10 |  3 | 2013-01-01 09:03:00 |      600 |
 |  5 | 2013-01-01 09:12:00 |       30 |  3 | 2013-01-01 09:03:00 |      600 |
 |  3 | 2013-01-01 09:03:00 |      600 |  4 | 2013-01-01 09:11:00 |       10 |
 |  3 | 2013-01-01 09:03:00 |      600 |  5 | 2013-01-01 09:12:00 |       30 |
 +----+---------------------+----------+----+---------------------+----------+

 or, if you prefer...

  SELECT *
    FROM my_table x
    JOIN my_table y
      ON y.id < x.id
     AND y.dt < (x.dt + INTERVAL x.duration SECOND)
     AND (y.dt + INTERVAL y.duration SECOND) > x.dt;
 +----+---------------------+----------+----+---------------------+----------+
 | id | dt                  | duration | id | dt                  | duration |
 +----+---------------------+----------+----+---------------------+----------+
 |  3 | 2013-01-01 09:03:00 |      600 |  2 | 2013-01-01 09:02:00 |      360 |
 |  4 | 2013-01-01 09:11:00 |       10 |  3 | 2013-01-01 09:03:00 |      600 |
 |  5 | 2013-01-01 09:12:00 |       30 |  3 | 2013-01-01 09:03:00 |      600 |
 +----+---------------------+----------+----+---------------------+----------+

对于“事件1”,2件事重叠(第2项和第3项)。 对于“事件2”,2件事重叠(第3项和第4项)。 对于“事件3”,有两件事重叠(第3项和第5项)。

   9.00  9.01  9.02  9.03  9.04  9.05  9.06  9.07  9.08  9.09  9.10  9.11  9.12  9.13
 1   |-|
 2               |-----------------------------------|
 3                     |-----------------------------------------------------------|
 4                                                                     |-|
 5                                                                           |-|

如果您愿意,我们可以这样说:

nothing overlaps item 1
1 thing overlaps item 2 (item 3), 
3 things overlap item 3 (items 2, 4, & 5), and
1 thing (item 3) overlaps each of items 4 & 5!


 SELECT x.id
      , COUNT(y.id) overlaps
    FROM my_table x
    LEFT
    JOIN my_table y
      ON y.id <> x.id
     AND y.dt < (x.dt + INTERVAL x.duration SECOND)
     AND (y.dt + INTERVAL y.duration SECOND) > x.dt
   GROUP
      By x.id;

 +----+----------+
 | id | overlaps |
 +----+----------+
 |  1 |        0 |
 |  2 |        1 |
 |  3 |        3 |
 |  4 |        1 |
 |  5 |        1 |
 +----+----------+   

一个简单的ORDER BY和LIMIT,你会得到最高的这些。

我不接受付款 - 但有些观点会很好!