0

我有两个子查询,我只想按第一个表的开放日期和关闭日期之间的日期范围加入。

第一个表示例:

| 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 中没有相等的键可以用来连接它们。

谢谢!

4

1 回答 1

0

将连接条件移至 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
;
于 2019-10-04T08:34:14.047 回答