Следующее должно работать в стандартном SQL ...
SELECT
to_date(t1.date_id),
count(distinct t2.userid)
FROM
t1
LEFT JOIN
t2
ON to_date(t2.createddate) >= date_sub(to_date(t1.date_id), 2)
AND to_date(t2.createddate) < date_add(to_date(t1.date_id), 1)
GROUP BY
to_date(t1.date_id)
Это будет , однако будет медленным. Поскольку вы храните даты в виде строк, используйте to_date () для их преобразования в даты. Это означает, что индексы не могут быть использованы, и механизм SQL не может сделать что-нибудь умное, чтобы уменьшить затрачиваемое усилие.
В результате каждая возможная комбинация строк должна сравниваться. Если у вас есть 100 записей в T1 и 10000 записей в T2, ваш механизм SQL обрабатывает миллион комбинаций.
Если вы храните эти значения как даты, вам не нужно to_date()
. И если вы индексируете даты, механизм SQL может быстро найти указанный диапазон дат.
ПРИМЕЧАНИЕ. Формат предложения ON
означает, что вам не нужно округлять t2.createddate
до дневного значения.
РЕДАКТИРОВАТЬ Почему ваш код не работает ...
SELECT to_date(t1.date_id), count(distinct t2.userid) FROM t1 JOIN t2
ON (to_date(t2.createddate) = to_date(t1.date_id))
WHERE date_sub(to_date(t2.createddate),0) > date_sub(to_date(t1.date_id), 3)
AND to_date(t2.createddate) <= to_date(t1.date_id)
GROUP by to_date(t1.date_id);
Это соединяет t1 с t2 с предложением ON
, равным (to_date(t2.createddate) = to_date(t1.date_id))
. Так как объединение является LEFT OUTER JOIN, значения в t2.createddate
ДОЛЖНЫ теперь либо быть NULL (нет совпадений), либо совпадать с t1.date_id
.
Предложение WHERE
допускает гораздо более широкий диапазон (3 дня). Но пункт ON
в JOIN
уже ограничил ваши данные одним днем.
Пример, который я привел выше, просто берет ваше предложение WHERE
и помещает его вместо старого предложения ON
.
EDIT
Hive не допускает <=
и >=
в предложении ON? Вы действительно настроены на использование HIVE ???
Если вы действительно, как насчет МЕЖДУ?
SELECT
to_date(t1.date_id),
count(distinct t2.userid)
FROM
t1
LEFT JOIN
t2
ON to_date(t2.createddate) BETWEEN date_sub(to_date(t1.date_id), 2) AND date_add(to_date(t1.date_id), 1)
GROUP BY
to_date(t1.date_id)
В качестве альтернативы, можно реорганизовать таблицу дат, чтобы перечислить даты, которые вы хотите включить ...
TABLE t1 (calendar_date, inclusive_date) =
{ 2011-01-03, 2011-01-01
2011-01-03, 2011-01-02
2011-01-03, 2011-01-03
2011-01-04, 2011-01-02
2011-01-04, 2011-01-03
2011-01-04, 2011-01-04
2011-01-05, 2011-01-03
2011-01-05, 2011-01-04
2011-01-05, 2011-01-05 }
SELECT
to_date(t1.calendar_date),
count(distinct t2.userid)
FROM
t1
LEFT JOIN
t2
ON to_date(t2.createddate) = to_date(t1.inclusive_date)
GROUP BY
to_date(t1.calendar_date)