2014-10-02 58 views
0

MySQL noob問題:使用MySQL的活動關聯查詢

我有兩個實體「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中的每個活動週期,我想確定在同一時間範圍內活動的一組條形對象。

從以上foo的#1的採樣數據: 爲8:00和9:00(即在第一活動時期foo的#1)棒#1和棒#3都是活性, 之間10:00和11:00只有#3活躍, 在12點和13點之間#2和#3都是活躍的,等等。

一旦確定了這些集合,如果我可以確定它們的交集I將會得到我想要的答案(例如,#3號柱是唯一一個與foo對象#1同時處於活動狀態的柱狀對象)。

我想開發一個查詢,將返回此結果。理想情況下,這個查詢將遍歷整個數據庫並且吐出包含一個「foo」id和一個活動重合的「bar」id的行。

作爲一個起點,我想出了一個查詢來識別所有這些過程中富活動的各個時期都處於活動狀態欄的對象:

SELECT foo.id, 
     bar.id 
FROM foo 
LEFT JOIN bar 
ON bar.start >= foo.arrive 
AND bar.end <= foo.depart; 

不過,我不知道在哪裏何去何從。一個相關的子查詢似乎可能是有用的,但我沒有太多的運氣制定一個沒有錯誤。我甚至不確定這是否是正確的方法。

有什麼建議嗎?

+0

你能給我們一個你想要的輸出應該是什麼樣子的例子嗎? – Arun 2014-10-02 19:43:52

+0

您的查詢只考慮在foo的期間開始和結束的小節。他們不能部分重疊嗎? – 1010 2014-10-02 21:50:39

+0

Arun我在尋找的輸出只是foo ID和匹配的條形碼ID; Ollie瓊斯的答案釘了它。 @ 1010不,我特別想排除所有重疊的情況。 – swarga 2014-10-03 16:19:01

回答

0

據我所見,您的JOIN查詢是正確的。它提取完全包含在(到達 - 離開)時間間隔內的(開始 - 結束)間隔。 JOIN是正確的選擇。

添加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小提琴。 http://sqlfiddle.com/#!2/68b7dc/3/0

然後,你要做的是統計你擁有的不同「foo」物品的數量,並計算不同組合的數量。然後你加入他們,你會得到你想要的結果。 http://sqlfiddle.com/#!2/ed5ac/5/0

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 

我認爲這是做你想做的。但是,如果沒有更徹底的解釋,很難確定。

+0

我同意。我會交換連接和左連接以包含沒有酒吧的foos。 – 1010 2014-10-02 21:59:00