使用ID和DATE连接,并使用Impala仅选择日期范围内的相关行

xpcnnkqh  于 2022-10-07  发布在  Impala
关注(0)|答案(2)|浏览(318)

我在HDFS中有两个表,我想使用Impala加入它们。一张table叫‘cust’,另一张叫‘Items’。下面在结尾处分享了创建这些表的代码。

客户:

id     date_start
212175  20/05/2022
286170  18/05/2022
361739  10/08/2021
297438  20/01/2022
415712  30/07/2021

项目:

id      item    date_sent
212175  PX002   21/05/2022
212175  PY005   10/05/2022
212175  PX003   01/06/2022
212175  PX003   01/07/2021
212175  NX002   15/08/2022
286170  PX002   19/05/2022
286170  PY005   10/07/2022
286170  PX003   15/07/2022
286170  PX003   10/04/2022
286170  NX002   15/06/2022

所需输出:

id       item      date
212175  PX002   21/05/2022
212175  PX003   01/06/2022
212175  PX005   10/05/2022
286170  PX002   19/05/2022
286170  PY005   10/07/2022
286170  PX003   15/07/2022
286170  NX002   15/06/2022

因此,我需要找到在两个日期之间发送给所有客户的所有物品。开始日期应该取自Customers表(每个客户有不同的开始日期),它被称为‘DATE_START’,而每个人的结束日期是12/08/2022。

在输出表中,我们可以看到,对于ID=212175,只显示了3个项目。这是因为窗口20/05/2022-12/08/2022期间只发送了3个项目。

对于ID=286170,只有1个项目‘PX003’没有显示在所需的输出中,这是因为该项目的发送日期为‘10/04/2022年’,该日期早于客户286170的DATE_START(2022年5月18日)。

到目前为止,我编写的查询是:

select c.id, type, c.date_start ,i.date_sent from cust c
left join items   i
on c.id = i.id
where i.date_sent <= '12/08/2022'

此查询考虑结束日期,但不考虑开始日期。我如何更改这一点,使我的结果与所需输出中的结果相同?感谢您的帮助,谢谢。

用于创建表的代码:

CREATE EXTERNAL TABLE cust (
id BIGINT, date_start STRING )   

INSERT INTO cust (id, date_start)
VALUES 
( (212175,'20/05/2022'),
  (286170,'18/05/2022'),
  (361739,'10/08/2021'),
  (297438,'20/01/2022'),
  (415712,'30/07/2021')

);

-- Create the items table 
CREATE EXTERNAL TABLE items (
id BIGINT, type STRING, date_sent STRING )   

-- Types table 
INSERT INTO items (id, type, date_sent)
VALUES 
( (212175,'PX002', '21/05/2022'),
(212175,'PY005', '10/05/2022'),
(212175,'PX003', '01/06/2022'),
(212175,'PX003', '01/07/2021'),
(212175,'NX002', '15/08/2022'),
(286170,'PX002', '19/05/2022'),
(286170,'PY005', '10/07/2022'),
(286170,'PX003', '15/07/2022'),
(286170,'PX003', '10/04/2022'),
(286170,'NX002', '15/06/2022')

);
hujrc8aj

hujrc8aj1#

您的方法是正确的,只需将字符串转换为日期即可。

请注意,您以字符串格式存储日期,需要使用TO_TIMESTAMP(str,‘dd/MM/yyyy’)转换为时间戳,然后进行比较。因此,您的SQL应该是

select c.id, type, c.date_start ,i.date_sent from cust c
left join items   i
on c.id = i.id
where to_timestamp(i.date_sent,'dd/MM/yyyy') <= to_timestamp('12/08/2022','dd/MM/yyyy')

如果您以yyyy-MM-dd格式(默认)存储数据,Imala将捕获该日期,那么您的SQL就可以工作了。

sg2wtvxw

sg2wtvxw2#

下面的解决方案让我得到了我想要的结果。

select merged.* from  
(select c.id, c.date_start, i.type, i.date_sent, to_timestamp(c.date_start, 'dd/MM/yyyy') as time_start, to_timestamp(i.date_sent, 'dd/MM/yyyy') as time_sent from cust c
inner join items   i
on c.id = i.id) merged 

where merged.time_sent <= '2022-08-14 00:00:00'
and merged.time_start <= merged.time_sent

相关问题