5
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;

通过使用上述查询,我​​得到以下输出。

USER_ID     |    PRODUCT_ID    |   TIMESTAMPS
------------+------------------+-------------
1015826235       220003038067      1004841621
1015826235       300003861266      1005268799
1015826235       140002997245      1061569397
1015826235      *200002448035*     1005542471

如果您比较上面的output from the query with the below Table2 data,那么product_id中的与下面数据中最后一行中的last line of above output不匹配。ITEM_IDTable2

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

所以我的问题是

查找所有PRODUCT_ID(ITEM_ID)与特定 BUYER_ID 或 USER_ID 对应的数据TIMESTAMPS(CREATED_TIME)不匹配的和。Table2

所以我需要为上面的例子显示这样的结果 -

BUYER_ID   |     ITEM_ID       |      CREATED_TIME       |     USER_ID   |       PRODUCT_ID     |   TIMESTAMPS
-----------+-------------------+-------------------------+---------------+------------------+------------------
1015826235     *210002448035*       2001-11-11 22:21:11     1015826235      *200002448035*     1005542471

我需要加入我用 table2 编写的上述查询以获得上述结果。所以我需要在 JOINING 过程中使用我上面的查询。这让我很困惑。任何建议将不胜感激。

更新:-

我编写了以下查询,但不知何故我无法实现我想要实现的输出。谁能帮我这个?

SELECT table2.buyer_id, table2.item_id, table2.created_time 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 JOIN table2 where 
prod_and_ts.user_id = table2.buyer_id
and (product_id <> table2.item_id or 
timestamps <> UNIX_TIMESTAMP(table2.created_time));
4

2 回答 2

2

我认为你可以用两个查询来做你想做的事,但我不是 100% 确定。通常在这种情况下,在第一个表中找到与第二个表不匹配的内容就足够了。您还试图获得“最接近”的匹配,这就是为什么这是具有挑战性的。

以下查询查找用户 id 和其他两个字段之一的匹配项,然后将它们组合起来:

SELECT table2.buyer_id, table2.item_id, table2.created_time, prod_and_ts.*
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 JOIN
     table2
     on prod_and_ts.user_id = table2.buyer_id and
        prod_and_ts.product_id = table2.item_id and
        prod_and_ts.timestamps <> UNIX_TIMESTAMP(table2.created_time)
union all
SELECT table2.buyer_id, table2.item_id, table2.created_time, prod_and_ts.*
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 JOIN
     table2
     on prod_and_ts.user_id = table2.buyer_id and
        prod_and_ts.product_id <> table2.item_id and
        prod_and_ts.timestamps = UNIX_TIMESTAMP(table2.created_time)

这不会找到任何一个字段都不匹配的情况。

另外,我使用“on”语法而不是“where”来编写它。我认为 HIVE 支持这一点。

于 2012-07-11T13:52:58.523 回答
1

您的代表太高,无法打开重复,尤其是同一问题的 2 个重复。

使用 HiveQL(Hadoop) 在 Hive 中连接两个表

加入两个表并从它们中获取输出

您没有足够的信息来为第三种情况绑定记录。
您可以FULL OUTER JOIN使用 anOR并取回所有内容,匹配您在列出的第一种和第二种情况下拥有足够信息的行,并通过从不匹配的字段返回带有空值的行来识别您没有的记录第三种情况的表。

SELECT DATEPART(d,B.T1time),DATEPART(d,A.Created_TIME),* 
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)

尝试在第三种情况下进行匹配是一种黑客行为 - 信息不存在

这会将它们与指定日期的任何其他日期不匹配的日期匹配,但您将再次获得笛卡尔积。

SELECT DATEPART(d,B.T1time),DATEPART(d,A.Created_TIME),* 
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)
    OR
    (
        (A.Created_TIME <>  B.t1time AND B.PRODUCTID <> A.ITEM_ID AND DATEPART(d,B.T1time) = DATEPART(d,A.Created_TIME)) 
        AND a.ITEM_ID NOT IN(SELECT ITEM_ID
                   FROM SO_Table1HIVE A2
                   INNER JOIN SO_Table2HIVE B2 ON A2.BUYER_ID = B2.[USER_ID] AND (A2.Created_TIME =  B2.t1time OR B2.PRODUCTID = A2.ITEM_ID)
                   )

        AND B.PRODUCTID NOT IN(SELECT PRODUCTID
                   FROM SO_Table1HIVE A2
                   INNER JOIN SO_Table2HIVE B2 ON A2.BUYER_ID = B2.[USER_ID] AND (A2.Created_TIME =  B2.t1time OR B2.PRODUCTID = A2.ITEM_ID)
                   )
    )

)

如果这不是 Hive 问题,您可以使用RANK()或尝试 atop one等, RANK()或者ROW_NO可能是这些 hack 中最好的,但我知道您使用的是 HQL,所以我不会写出来。您可以将它们拉到一个单独的表中并运行一些逻辑更新查询来更新它,然后将其用作查找表来绑定。

 tbl1Tbl2Lookup
 ---------------
 id int identity
 table1info FK
 table2info FK 

您可能应该做的是问题中的人建议您提供赏金 - 因为您确实没有查询第三种情况的好方法,他们为您提供了特定于 HIVE 的替代方案。

于 2012-07-11T20:02:57.863 回答