【问题标题】:SQL Query JOIN with TableSQL 查询 JOIN 与表
【发布时间】:2012-07-08 20:19:18
【问题描述】:
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,那么last line of above output中的product_id与下面Table2数据中最后一行的ITEM_ID不匹配。

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

所以我的问题是

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

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

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

【问题讨论】:

  • 我正在使用 Hive,并且 Hive 支持类似 SQL 的语法,因此我将此问题标记为 sqljoin。所以 JOIN 将在 HIVE 中工作。我基本上只需要加入。所以我认为Oracle语法会很好。
  • 为什么最后一行不匹配?是不是因为时间戳和创建时间不匹配?
  • 我不确定我写的实际查询是否正确。这让我很困惑。所以不确定上面的查询是否正确。
  • 您的查询看起来不错;通过替换上面查询中的所有内容来尝试以下 JOIN ) prod_and_ts : LEFT JOIN table2 where prod_and_ts.user_id = table2.buyer_id and product_id = table2.item_id AND timestamps = UNIX_TIMESTAMP(table2.created_time) WHERE table2.item_id IS NULL - 这应该选择在用户、产品和时间戳上不匹配的所有行
  • 我不确定您的查询是否正确,因为您提到的查询中有两个 where 子句。你确定你的查询是正确的?

标签: sql join hive


【解决方案1】:

我认为你可以用两个查询来做你想做的事,但我不能 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 支持这一点。

【讨论】:

    【解决方案2】:

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

    Joining two Tables in Hive using HiveQL(Hadoop)

    Join Two Tables and get the output from both of them

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

    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)
                       )
        )
    
    )
    

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-06
      • 2017-12-21
      • 2014-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多