Я пытаюсь подсчитать строки в таблице events
, где дата в столбце EventDate
происходит между двумя датами, указанными в другой таблице customers
.MySQL подсчитывает строки в одной таблице на основе дат в другой таблице
КЛИЕНТЫ
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 раза появляется в events
, но первая дата не лежит между EventTo
и EventFrom
поэтому не должен» т. ID 4 появляется три раза в 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
и 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
имеет около 1,5 миллионов строк, но все же запрос, кажется, занимает неоправданно долгое время. Есть ли лучший способ структурирования этого?
Идея: использовать внутреннее соединение вместо левого присоединиться к подсчету, а затем использовать другой запрос для добавления нулей в наборе результатов, если вы действительно нуждаетесь в них (возможно, нет?). И вы, похоже, не считаете события в любом месте вашего запроса, вопреки своим требованиям в первом предложении. –
Является ли COUNT (events.ID) не считая событий? Мне не обязательно нужны нули, просто это подмножество большего запроса, и я хочу, чтобы все строки в «клиентах» возвращались для других целей. – MadScone
Извините, упустил счет во внутреннем запросе, вы правы. –