我有一个表VISIT_INFO,包含以下列:
pers_key - unique identifyer for each person
pers_name - name of person
visit_date - date at which they visited a business
另一个表VALID_DATES,包含以下列:
condition - string
start_date - date
end_date - date
我目前有以下查询:
select pers_key, pers_name from VISIT_INFO a
CROSS JOIN
(select start_date, end_date from VALID_DATES where condition = 'condition1') b
WHERE (a.visit_date >= b.start_date and a.visit_date <= b.end_date)
GROUP BY a.pers_key
所以&#39; condition1&#39;有一个特定的start_date和end_date。我需要为两个日期之间的访问过滤VISIT_INFO。我想知道是否有更有效的方法来做到这一点。根据我目前的理解,它目前必须遍历整个表(数百万行)并将start_date和end_date添加到每一行。那么它是否必须再次遍历每一行并测试WHERE条件?
我问这个是因为当我删除交叉连接并对condition1硬编码start_date和end_date时,它花费的时间要少得多。我试图在日期中避免硬编码,因为这将导致严重的单调乏味。
重申一下,有没有更好的方法来过滤VALIS_DATES中特定日期的VISIT_INFO?
编辑:我刚刚意识到我遗漏了一条相当大的信息,因为这都属于HIVE。所以EXISTS和加入(在b和c之间)是不可能的。
答案 0 :(得分:1)
怎么样:
SELECT DISTINCT pers_key, pers_name
FROM visit_info
WHERE EXISTS
(
SELECT 1
FROM valid_dates
WHERE condition = 'condition1'
AND visit_date BETWEEN start_date AND end_date
);
答案 1 :(得分:0)
with dt as (select start_date, end_date from VALID_DATES where condition = 'condition1')
select a.pers_key, a.pers_name
from VISIT_INFO a
JOIN dt on a.visit_date between dt.start_date and dt.end_date
GROUP BY a.pers_key
答案 2 :(得分:0)
尝试exists
版本绝对是可能的。但是,您可能最好扩展VALID_DATES
表,因此每个日期有一行。
然后,查询:
select vi.*
from VISIT_INFO vi JOIN
VALID_DATES_expanded vde
ON vi.visit_date = vde.valid_date
where vde.condition = 'condition1';
可以使用VISIT_INFO(visit_date)
和VALID_DATES_expanded(condition, valid_date)
上的索引。如果VISIT_INFO
非常大且查询选择了相对较少的行,这可能是解决此问题的最快方法。