Как присоединиться исключительно по диапазону дат в Hive SQL? - PullRequest
0 голосов
/ 03 октября 2019

У меня есть два подзапроса, к которым я хотел бы присоединиться только по диапазону дат между открытой и закрытой датами из первой таблицы.

Пример первой таблицы:

| id_original | open_datetime     | close_datetime    |
|-------------|-------------------|-------------------|
|      1      |2019-01-01 10:00:02|2019-01-02 11:00:21|
|      2      |2019-01-01 10:05:52|2019-01-05 16:45:12|
|      3      |2019-01-03 00:00:43|2019-01-03 23:12:44|

Вторая таблицапример:

| category | all other columns...| open_date         |
|----------|---------------------|-------------------|
|    A     |        ...          |2019-01-01 11:00:00|
|    B     |        ...          |2019-01-02 19:10:10|
|    C     |        ...          |2019-01-03 08:23:45|
|    D     |        ...          |2019-01-04 18:10:53|

Желаемый вывод:

| id_original | category | all other columns...| open_date         |
|-------------|----------|---------------------|-------------------|
|      1      |    A     |        ...          |2019-01-01 11:00:00|
|      2      |    A     |        ...          |2019-01-01 11:00:00|
|      2      |    B     |        ...          |2019-01-02 19:10:10|
|      2      |    C     |        ...          |2019-01-03 08:23:45|
|      2      |    D     |        ...          |2019-01-04 18:10:53|
|      3      |    C     |        ...          |2019-01-03 08:23:45|

Это мой код:

SELECT *
FROM (
    SELECT id, open_datetime, close_datetime
    FROM table1
    WHERE id IN (list_of_ids)
) t1
LEFT JOIN (
    SELECT *
    FROM table2
    WHERE other_conditions
) t2 ON t2.open_date >= t1.open_datetime AND t2.open_date <= t1.close_datetime

Я знаю, что Hive SQL не поддерживает неравенство в качестве условия дляJOIN. Но как мне подойти к этому вопросу?

Примечание: объединение, которое мне нужно, предназначено исключительно для дат, нет равных ключей от t1 и t2, которые я могу использовать для их соединения.

Спасибо!

1 Ответ

0 голосов
/ 04 октября 2019

Переместите условие соединения в предложение WHERE. В этом случае LEFT JOIN преобразуется в CROSS, потому что у вас нет других условий соединения, а соединение без условий является CROSS-join. После перекрестного соединения отфильтруйте строки в предложении WHERE. Хотя соединение CROSS может вызвать серьезные проблемы с производительностью, если невозможно отфильтровать строки или объединить по другому ключу, чтобы избежать использования продукта CROSS. Если одна из таблиц достаточно мала, чтобы поместиться в памяти, CROSS-join будет выполнен как map-join, это также поможет повысить производительность.

set hive.auto.convert.join=true;
set hive.mapjoin.smalltable.filesize=512000000; --try to set it bigger and see if map-join works
                                                --setting too big value may cause OOM exception 

SELECT *
FROM (
    SELECT id, open_datetime, close_datetime
    FROM table1
    WHERE id IN (list_of_ids)
) t1
CROSS JOIN 
(
    SELECT *
    FROM table2
    WHERE other_conditions
) t2 
WHERE (t2.open_date >= t1.open_datetime AND t2.open_date <= t1.close_datetime)
   OR t2.category is NULL --to allow absence of t2 like in LEFT join
;
...