ars*_*nal 5 sql hadoop hive mapreduce hiveql
CREATE EXTERNAL TABLE IF NOT EXISTS TestingTable1 (This is the MAIN table through which comparisons need to be made)
(
BUYER_ID BIGINT,
ITEM_ID BIGINT,
CREATED_TIME STRING
)
Run Code Online (Sandbox Code Playgroud)
这是上面第一个表格中的数据
**BUYER_ID** | **ITEM_ID** | **CREATED_TIME**
--------------+------------------+-------------------------
1015826235 220003038067 *2001-11-03 19:40:21*
1015826235 300003861266 2001-11-08 18:19:59
1015826235 140002997245 2003-08-22 09:23:17
1015826235 *210002448035* 2001-11-11 22:21:11
Run Code Online (Sandbox Code Playgroud)
这是Hive中的第二个表 - 它还包含有关我们正在购买的项目的信息.
CREATE EXTERNAL TABLE IF NOT EXISTS TestingTable2
(
USER_ID BIGINT,
PURCHASED_ITEM ARRAY<STRUCT<PRODUCT_ID: BIGINT,TIMESTAMPS:STRING>>
)
Run Code Online (Sandbox Code Playgroud)
这是上面第二个表(TestingTable2)中的数据 -
**USER_ID** **PURCHASED_ITEM**
1015826235 [{"product_id":220003038067,"timestamps":"1004941621"}, {"product_id":300003861266,"timestamps":"1005268799"}, {"product_id":140002997245,"timestamps":"1061569397"},{"product_id":200002448035,"timestamps":"1005542471"}]
Run Code Online (Sandbox Code Playgroud)
比较TestingTable2有TestingTable1让下面的情形得到满足.
查找PRODUCT_ID和TIMESTAMPS来自TestingTable2这不相匹配ITEM_ID和CREATED_TIME从TestingTable1在相应于BUYER_ID(USER_ID)从对比后TestingTable1.
因此,如果您查看TestingTable2数据(最后)ITEM_ID 210002448035来自 数据TestingTable1不匹配,TestingTable2 PRODUCT_ID- 200002448035并且与时间戳类似.所以我想使用HiveQL查询显示以下结果.
**BUYER_ID** | **ITEM_ID** | **CREATED_TIME** | **PRODUCT_ID** | **TIMESTAMPS**
--------------+------------------+--------------------------------+------------------------+----------------------
1015826235 *210002448035* 2001-11-11 22:21:11 200002448035 1005542471
1015826235 220003038067 *2001-11-03 19:40:21* 220003038067 1004941621
Run Code Online (Sandbox Code Playgroud)
谁能帮我这个.因为我是HiveQL的新手,所以有很多问题.
更新:-
我写了这个查询,但它没有按照我想要的方式工作.
select * from
(select * from
(select user_id, prod_and_ts.product_id as product_id, prod_and_ts.timestamps as timestamps
from testingtable2 LATERAL VIEW
explode(purchased_item) exploded_table as prod_and_ts)
prod_and_ts
LEFT OUTER JOIN testingtable1
ON ( prod_and_ts.user_id = testingtable1.buyer_id AND testingtable1.item_id = prod_and_ts.product_id
AND prod_and_ts.timestamps = UNIX_TIMESTAMP (testingtable1.created_time)
)
where testingtable1.buyer_id IS NULL)
set_a LEFT OUTER JOIN testingtable1
ON (set_a.user_id = testingtable1.buyer_id AND
( set_a.product_id = testingtable1.item_id OR set_a.timestamps = UNIX_TIMESTAMP(testingtable1.created_time) )
);
Run Code Online (Sandbox Code Playgroud)
再一次更新
根据user1166147评论.我按照他的查询编写了我的查询.在蜂巢中我猜INNER JOIN是简单地写的JOIN.
这是我的下面的查询.
select * from (select t2.buyer_id, t2.item_id, t2.created_time as created_time, subq.user_id, subq.product_id, subq.timestamps as timestamps
from
(select user_id, prod_and_ts.product_id as product_id, prod_and_ts.timestamps as timestamps from testingtable2 lateral view explode(purchased_item) exploded_table as prod_and_ts) subq JOIN testingtable1 t2 on t2.buyer_id = subq.user_id
AND subq.timestamps = unix_timestamp(t2.created_time)
WHERE (subq.product_id <> t2.item_id)
union all
select t2.buyer_id, t2.item_id as item_id, t2.created_time, subq.user_id, subq.product_id as product_id, subq.timestamps
from
(select user_id, prod_and_ts.product_id as product_id, prod_and_ts.timestamps as timestamps from testingtable2 lateral view explode(purchased_item) exploded_table as prod_and_ts) subq JOIN testingtable1 t2 on t2.buyer_id = subq.user_id
and subq.product_id = t2.item_id
WHERE (subq.timestamps <> unix_timestamp(t2.created_time))) unionall;
Run Code Online (Sandbox Code Playgroud)
运行上面的查询后,我得到零结果.
最后一次更新: -
我的坏,我没有表中的准确数据,所以这就是我没有得到结果的原因.是的,它正在运行上面的实际查询.
编辑 - 第1部分 好的 - 由于某种原因我将解释自己 - 所以首先我偶然发现了这个问题,因为SQL标签,并看到了Hive,并开始不看,只是跳过它.然后,我注意到它已经过了一天,你没有得到答案.我看了 - 我在发布的原始查询中看到了一个SQL逻辑更正,我知道这将需要并且会有所帮助,所以我发布的仅仅因为没有人回答.我将尝试解决这最后一个问题 - 但在此之后我会对自己保持建议,因为我可能会提出不好的建议.祝好运!我试过了!你现在似乎得到了答案,所以...
在TSQL中,我可以使用以下单个查询解决整个问题:
SELECT *
FROM SO_Table1HIVE A
FULL OUTER JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND (B.t1time = A.Created_TIME OR B.PRODUCTID = A.ITEM_ID)
Run Code Online (Sandbox Code Playgroud)
它会返回所有内容,包括仅匹配的buyer_id/user_id.它不会匹配在另一个表中的时间或产品中没有匹配的buyer_id/user_id行,但它将在另一个表的字段中将其作为单独的行返回NULLS.我不会以任何方式匹配这些 - 如下所述,没有提供准确的信息.
结束编辑第1部分
如果你不能做到FULL OUTER JOIN与OR在蜂房,以满足原标准的最简单方法是UNION ALL2 INNER JOIN秒.在其中一个查询中,除了加入匹配的user_ids之外,还要加入PRODUCT_ID和您WHERE查找的与CREATED_TIME不匹配的TIMESTAMPS.在第二个查询中,除了加入匹配的user_ids之外,还要加入时间和WHERE查找不匹配的产品.
编辑第2部分 - 评论问题补充标准的更新
如果我理解了最后一个条件,那么任何一个表中的任何记录都有匹配的user_id = buyer_id,但没有其他匹配.在FULL OUTER JOIN与OR条件将返回他们,但没有一种方法来关联记录,以相互提供足够的信息.我们可以轻松识别它们,但无法将它们相互联系起来.如果您这样做并且在两个表中都有多个记录而没有匹配,则每个记录将有多个条目.
我写的任何查询试图绑定它们没有更多的信息(可能与)将是一个猜测和不准确.
例如,在第一个表中,如果除了user_id之外,第二个表中没有匹配的2个(样本伪造)记录:
1015826235 420003038067 2011-11-03 19:40:21.000
1015826235 720003038067 2004-11-03 19:40:21.000
Run Code Online (Sandbox Code Playgroud)
在表2中 - 这些不匹配:
1015826235 {"product_id":520003038067,"timestamps":"10...
1015826235 {"product_id":620003038067,"timestamps":"10...
Run Code Online (Sandbox Code Playgroud)
您可以识别它们,但如果您在没有更多条件的情况下匹配它们,则会获得4而不是2:
1015826235 420003038067 2011-11-03 19:40:21.000 1015826235 520003038067
1015826235 420003038067 2011-11-03 19:40:21.000 1015826235 620003038067
1015826235 720003038067 2004-11-03 19:40:21.000 1015826235 520003038067
1015826235 720003038067 2004-11-03 19:40:21.000 1015826235 620003038067
Run Code Online (Sandbox Code Playgroud)
我的建议只是识别它们并显示它们,如下所示.
BUYER_ID ITEM_ID CREATED_TIME USER_ID PRODUCTID timestamps
----------------------------------------------------------------------
NULL NULL NULL 1015826235 520003038067 2009-11-11 22:21:11.000
NULL NULL NULL 1015826235 620003038067 2008-11-11 22:21:11.000
1015826235 420003038067 2011-11-03 19:40:21.000 NULL NULL NULL
1015826235 720003038067 2004-11-03 19:40:21.000 NULL NULL NULL
Run Code Online (Sandbox Code Playgroud)
结束编辑第2部分 - 评论问题的更新附加标准 - 第1部分
我正在使用TSQL,因此我无法使用您的语法测试您的确切查询,但连接的概念是相同的,这将返回您想要的.我确实接受了您的查询并尝试您的语法,根据需要进行修改.我在TSQL中测试过.您可以通过HiveQL中的功能获取并改进它.还有其他方法可以做到这一点 - 但这是最直接的,这将转化为HiveQL.
删除,你得到这个部分,它包括在内
(再次根据需要修改语法)**
SELECT *
FROM (
SELECT BUYER_ID,ITEM_ID,CREATED_TIME,PRODUCT_ID,TIMESTAMPS
FROM testingtable2 LATERAL VIEW
explode(purchased_item) exploded_table as prod_and_ts)
prod_and_ts
INNER JOIN table2 A ON A.BUYER_ID = prod_and_ts.[USER_ID] AND prod_and_ts.timestamps = UNIX_TIMESTAMP (table2.created_time)
WHERE prod_and_ts.product_id <> A.ITEM_ID
UNION ALL
SELECT BUYER_ID,ITEM_ID,CREATED_TIME,PRODUCT_ID,TIMESTAMPS
FROM testingtable2 LATERAL VIEW
explode(purchased_item) exploded_table as prod_and_ts)
prod_and_ts
INNER JOIN table2 A ON A.BUYER_ID = prod_and_ts.[USER_ID] AND prod_and_ts.product_id = A.ITEM_ID
WHERE prod_and_ts.timestamps <> UNIX_TIMESTAMP (table2.created_time)
) X
Run Code Online (Sandbox Code Playgroud)
这是我测试的TSQL版本,带有我的表名作为参考:
SELECT *
FROM(
SELECT *
FROM SO_Table1HIVE A
INNER JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND B.t1time = A.Created_TIME
WHERE B.PRODUCTID <> A.ITEM_ID
UNION ALL
SELECT *
FROM SO_Table1HIVE A
INNER JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND B.PRODUCTID = A.ITEM_ID
WHERE B.t1time <> A.Created_TIME
) X
Run Code Online (Sandbox Code Playgroud)
*编辑第3部分 - 更新评论问题附加标准 - 第2部分
在TSQL中,可以使用FULL OUTER JOIN带有OR连接条件的整个查询(无联合)运行
SELECT *
FROM SO_Table1HIVE A
FULL OUTER JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND (B.t1time = A.Created_TIME OR B.PRODUCTID = A.ITEM_ID)
Run Code Online (Sandbox Code Playgroud)
如果您不能简单地执行上述操作,那么对于新条件的SQL逻辑 - 从两个表中获取不匹配的那些并NULL在其他表中显示它们使用RIGHT JOIN和LEFT JOIN.
RIGHT JOIN将抓住第一个表中的任何内容匹配第二个和第二个中的所有内容,并LEFT执行相反的操作.将新查询添加到您的UNION.
TSQL示例 - 改进HIVE
SELECT *
FROM SO_Table1HIVE A
RIGHT JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND (B.t1time = A.Created_TIME OR B.PRODUCTID = A.ITEM_ID)
WHERE A.BUYER_ID IS NULL
UNION ALL
SELECT *
FROM SO_Table1HIVE A
LEFT JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID] AND (B.t1time = A.Created_TIME OR B.PRODUCTID = A.ITEM_ID)
WHERE B.[USER_ID] IS NULL
Run Code Online (Sandbox Code Playgroud)
或者,如果你想抓住它们并将它们匹配为重复项,请添加到UNION:
TSQL
SELECT *
FROM SO_Table1HIVE A
JOIN SO_Table2HIVE B ON A.BUYER_ID = B.[USER_ID]
WHERE B.t1time NOT IN(SELECT Created_TIME FROM SO_Table1HIVE)
AND A.Created_TIME NOT IN(SELECT t1time FROM SO_Table2HIVE)
AND B.PRODUCTID NOT IN(SELECT ITEM_ID FROM SO_Table1HIVE)
AND A.ITEM_ID NOT IN(SELECT PRODUCTID FROM SO_Table2HIVE)
Run Code Online (Sandbox Code Playgroud)
祝你好运!
| 归档时间: |
|
| 查看次数: |
59246 次 |
| 最近记录: |