events
列の日付EventDate
が別のテーブルで指定された 2 つの日付の間にあるテーブルの行を数えようとしていますcustomers
。
顧客
ID EventFrom EventTo
-- ---------- -----------
1 2011-01-01 2012-01-01
2 2012-12-10 2013-12-10
3 2010-05-01 2011-05-01
4 2011-01-01 2012-01-01
5 2012-07-30 2013-07-30
6 2011-06-21 2012-06-21
7 2011-06-22 2012-06-22
8 2010-02-19 2011-02-19
イベント
ID EventDate
-- ----------
2 1999-01-01
2 2012-12-12
2 2012-12-13
3 1900-01-12
4 2011-02-10
4 2011-02-11
4 2011-02-12
結果
ID EventFrom EventTo Events
-- ---------- ----------- ------
1 2011-01-01 2012-01-01 0
2 2012-12-10 2013-12-10 2
3 2010-05-01 2011-05-01 0
4 2011-01-01 2012-01-01 3
5 2012-07-30 2013-07-30 0
6 2011-06-21 2012-06-21 0
7 2011-06-22 2012-06-22 0
8 2010-02-19 2011-02-19 0
ID 2 は に 2 回表示されますevents
が、最初の日付はその間EventTo
にEventFrom
ないため、カウントされません。ID 4 は に 3 回表示されevents
、すべてが正しい範囲内にあります。
私はそれを行うことができますが、ネストされた結合が非常に遅くなります。
SELECT customers.ID
, customers.EventFrom
, customers.EventTo
, IFNULL(e.Events, 0) AS 'Events'
FROM customers
LEFT JOIN (
SELECT events.ID, COUNT(events.ID) AS 'Events'
FROM events
INNER JOIN customers ON customers.ID = events.ID
AND events.EventDate BETWEEN customers.EventFrom AND customers.EventTo
GROUP BY events.ID
) e ON e.ID = customers.ID
EventDate
のインデックスとして設定しましたevents
。EventFrom
andもインデックスとして設定してみEventTo
ましたが、大きな違いはありませんでした。そして、このクエリはより大きなクエリの一部であるため、主要部分にインデックスを設定しました。
私もこれを試しました:
SELECT customers.ID
, customers.EventFrom
, customers.EventTo
, SUM(IF(events.EventDate BETWEEN customers.EventFrom AND customers.EventTo), 1, 0) AS 'Events'
FROM customers
LEFT JOIN events ON events.ID = customers.ID
これも信じられないほど遅いです。customers
約 150 万行ありますが、それでもクエリに非常に長い時間がかかるようです。これを構造化するより良い方法はありますか?