Join 单个SQL查询中的多连接

Join 单个SQL查询中的多连接,join,group-by,sql-order-by,hql,hive,Join,Group By,Sql Order By,Hql,Hive,下面是TestingTable1中的数据,总是按日期降序排列 BUYER_ID | ITEM_ID | CREATED_TIME ----------+-----------------+---------------------- 1345653 110909316904 2012-07-09 21:29:06 1345653 151851771618 2012-07-09 19:57:33 1345653 2210657967

下面是TestingTable1中的数据,总是按日期降序排列

BUYER_ID  |   ITEM_ID       |  CREATED_TIME
----------+-----------------+----------------------
1345653      110909316904     2012-07-09 21:29:06
1345653      151851771618     2012-07-09 19:57:33
1345653      221065796761     2012-07-09 19:31:48
1345653      400307563710     2012-07-09 18:57:33
USER_ID  |   PRODUCT_ID    |    LAST_TIME
---------+----------------+-----------------------
1345653     110909316904      2012-07-09 22:29:06
1345653     150851771618      2012-07-09 19:57:33    
如果这是测试表2中的以下数据,则始终按日期降序排序

BUYER_ID  |   ITEM_ID       |  CREATED_TIME
----------+-----------------+----------------------
1345653      110909316904     2012-07-09 21:29:06
1345653      151851771618     2012-07-09 19:57:33
1345653      221065796761     2012-07-09 19:31:48
1345653      400307563710     2012-07-09 18:57:33
USER_ID  |   PRODUCT_ID    |    LAST_TIME
---------+----------------+-----------------------
1345653     110909316904      2012-07-09 22:29:06
1345653     150851771618      2012-07-09 19:57:33    
TestingTable1
中的每一行都应该与
TestingTable2
匹配,如果不匹配或者TestingTable2中没有数据,那么我需要在输出中显示它们,就像在
TestingTable1
中一样,我有这个数据,但对应于
TestingTable2
我有这个数据(这将是错误的数据),这样我就可以看到什么是不匹配的,什么数据丢失了

我需要将
买家ID
用户ID
上的
测试表2
测试表1
进行比较。我要看看,如果
BUYER\u ID
USER\u ID
匹配,那么我需要将
ITEM\u ID
PRODUCT\u ID
CREATED\u TIME
LAST\u TIME
进行比较,如果在其中一个或两个中与
testingtable 1
进行比较后,
testingtable 2
中存在不匹配,然后我需要展示结果

如果你看上面的例子,我基本上有三种情况

  • 首先-在
    TestingTable1
    中,第一行
    ITEM\u ID
    TestingTable2
    第一行的
    PRODUCT\u ID
    匹配,但
    创建的时间
    与两个表中第一行的
    上次时间
    不匹配
  • 其次-在
    TestingTable1
    中,第二行
    创建的时间
    TestingTable2
    第二行的
    上次时间
    匹配,但
    项目ID
    与两个表中第二行的
    产品ID
    不匹配
  • 第三-在
    测试表1
    中,最后两行(行)根本不在
    测试表2
    中。我编写的查询中没有涉及此场景。我想在我的查询中也出现这种情况
  • 因此,在比较
    TestingTable2
    TestingTable1
    时,我需要介绍这三种情况。而
    TestingTable1
    是需要经常进行比较的主表,因此这意味着
    TestingTable1
    中的数据总是准确的

    因此,考虑到上述示例,如果其中一个不匹配,或者数据根本不在
    TestingTable2
    中-
    TestingTable1
    数据中,我需要显示如下结果,然后在其旁边显示相同的
    TestingTable2
    数据,这样我就可以看到
    TestingTable1
    TestingTable2

    BUYER_ID   |   ITEM_ID       |    CREATED_TIME           |      USER_ID   |     PRODUCT_ID     |     LAST_TIME   
    -----------+-----------------+---------------------------+----------------+--------------------+-----------------------
    1345653      110909316904       2012-07-09 21:29:06            1345653          110909316904      2012-07-09 22:29:06
    1345653      151851771618       2012-07-09 19:57:33            1345653          150851771618      2012-07-09 19:57:33
    1345653      221065796761       2012-07-09 19:31:48            NULL             NULL              NULL
    1345653      400307563710       2012-07-09 18:57:33            NULL             NULL              NULL
    
    下面是我编写的查询,它只涉及我上面提到的
    两个场景
    ,效果很好,我将获得如上所述的输出,并保留输出的最后两行。但是我还需要在这个(下面)查询中添加
    第三个场景
    ,这样它就可以给出如上所示的输出

    SELECT *
    FROM   (SELECT T2.buyer_id,
                   T2.item_id,
                   T2.created_time AS created_time,
                   subq.user_id,
                   subq.product_id,
                   subq.LAST_TIME
            FROM   TestingTable2 subq
                   JOIN TestingTable1 T2
                     ON T2.buyer_id = subq.user_id
                        AND subq.LAST_TIME = ( 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.LAST_TIME
            FROM   TestingTable2 subq
                   JOIN TestingTable1 T2
                     ON T2.buyer_id = subq.user_id
                        AND subq.product_id = T2.item_id
            WHERE  ( subq.LAST_TIME <> ( T2.created_time ) )) finalResult
    ORDER  BY finalResult.BUYER_ID;
    
    更新的SQL查询出现错误

    我用这个查询替换了
    TestingTable1
    -

    (SELECT BUYER_ID, ITEM_ID, rank(BUYER_ID), CREATED_TIME
    FROM (
        SELECT BUYER_ID, ITEM_ID, CREATED_TIME
        FROM testingtable1
        where to_date(from_unixtime(cast(UNIX_TIMESTAMP(CREATED_TIME) as int))) = '2012-07-09'
        DISTRIBUTE BY BUYER_ID
        SORT BY BUYER_ID, CREATED_TIME desc
    ) T1
    WHERE rank(BUYER_ID) < 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 where to_date(from_unixtime(cast(PROD_AND_TS.TIMESTAMPS as BIGINT))) = '2012-07-09')
    

    听起来你想要的是一个完整的外部连接。我在你的帖子中没有看到你使用的是什么类型的数据库,因此我无法给出确切的语法,但此链接可能会为你指明正确的方向:


    具体看一下底部的图表。

    听起来您要寻找的是一个完整的外部连接。我在你的帖子中没有看到你使用的是什么类型的数据库,因此我无法给出确切的语法,但此链接可能会为你指明正确的方向:


    具体看一下底部的图表。

    试试这段用SQL编写的代码。我已经在SQLFiddle上测试过了

     SELECT 
     tt1.buyer_id,tt1.item_id,tt1.created_time,
     tt2.user_id,tt2.product_id,tt2.last_time
     FROM 
     testingtable1 tt1 LEFT OUTER JOIN
     testingtable2 tt2 ON
     tt1.buyer_id = tt2.user_id
     AND 
     tt1.item_id = tt2.product_id
     AND
     tt1.created_time = tt2.last_time
    

    试试这段用SQL编写的代码。我已经在SQLFiddle上测试过了

     SELECT 
     tt1.buyer_id,tt1.item_id,tt1.created_time,
     tt2.user_id,tt2.product_id,tt2.last_time
     FROM 
     testingtable1 tt1 LEFT OUTER JOIN
     testingtable2 tt2 ON
     tt1.buyer_id = tt2.user_id
     AND 
     tt1.item_id = tt2.product_id
     AND
     tt1.created_time = tt2.last_time
    

    如果由于DBMS限制,您无法使用
    NOT IN
    @eggyal
    发布的干净解决方案,另一个选项可能是完全复制原始联合,并在
    左联合中使用这些结果

    应用于您的,下面的语句返回所需的结果

    SQL语句

    SELECT * 
    FROM(
        SELECT *
        FROM TestingTable1 A
        JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.LAST_TIME = A.Created_TIME 
        WHERE B.PRODUCT_ID <> A.ITEM_ID
        UNION ALL
        SELECT * 
        FROM TestingTable1 A
        INNER JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.PRODUCT_ID = A.ITEM_ID  
        WHERE B.LAST_TIME <> A.Created_TIME      
     ) X
    UNION ALL
    SELECT A.*, NULL, NULL, NULL
    FROM   TestingTable1 A
           LEFT OUTER JOIN (
                SELECT *
                FROM TestingTable1 A
                JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.LAST_TIME = A.Created_TIME 
                WHERE B.PRODUCT_ID <> A.ITEM_ID
                UNION ALL
                SELECT * 
                FROM TestingTable1 A
                INNER JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.PRODUCT_ID = A.ITEM_ID  
                WHERE B.LAST_TIME <> A.Created_TIME      
           ) X ON A.BUYER_ID = X.BUYER_ID AND A.ITEM_ID = X.ITEM_ID
    WHERE  X.BUYER_ID IS NULL
    
    选择*
    从(
    挑选*
    来自测试表1A
    在A.BUYER\u ID=B.USER\u ID和B.LAST\u TIME=A.Created\u TIME上加入TestingTable2 B
    其中B.产品标识A.项目标识
    联合所有
    选择*
    来自测试表1A
    A.BUYER\u ID=B.USER\u ID和B.PRODUCT\u ID=A.ITEM\u ID上的内部联接测试表2 B
    其中B.最后一次A.创建时间
    )X
    联合所有
    选择一个*,NULL,NULL,NULL
    来自测试表1A
    左外连接(
    挑选*
    来自测试表1A
    在A.BUYER\u ID=B.USER\u ID和B.LAST\u TIME=A.Created\u TIME上加入TestingTable2 B
    其中B.产品标识A.项目标识
    联合所有
    选择*
    来自测试表1A
    A.BUYER\u ID=B.USER\u ID和B.PRODUCT\u ID=A.ITEM\u ID上的内部联接测试表2 B
    其中B.最后一次A.创建时间
    )A.BUYER\u ID=X.BUYER\u ID和A.ITEM\u ID=X.ITEM\u ID上的X
    其中X.BUYER\u ID为空
    
    如果由于DBMS限制,您无法在
    中使用
    ,或
    @eggyal
    发布的干净解决方案,另一种选择可能是完全复制原始联合,并在
    左联合中使用这些结果

    应用于您的,下面的语句返回所需的结果

    SQL语句

    SELECT * 
    FROM(
        SELECT *
        FROM TestingTable1 A
        JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.LAST_TIME = A.Created_TIME 
        WHERE B.PRODUCT_ID <> A.ITEM_ID
        UNION ALL
        SELECT * 
        FROM TestingTable1 A
        INNER JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.PRODUCT_ID = A.ITEM_ID  
        WHERE B.LAST_TIME <> A.Created_TIME      
     ) X
    UNION ALL
    SELECT A.*, NULL, NULL, NULL
    FROM   TestingTable1 A
           LEFT OUTER JOIN (
                SELECT *
                FROM TestingTable1 A
                JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.LAST_TIME = A.Created_TIME 
                WHERE B.PRODUCT_ID <> A.ITEM_ID
                UNION ALL
                SELECT * 
                FROM TestingTable1 A
                INNER JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.PRODUCT_ID = A.ITEM_ID  
                WHERE B.LAST_TIME <> A.Created_TIME      
           ) X ON A.BUYER_ID = X.BUYER_ID AND A.ITEM_ID = X.ITEM_ID
    WHERE  X.BUYER_ID IS NULL
    
    选择*
    从(
    挑选*
    来自测试表1A
    在A.BUYER\u ID=B.USER\u ID和B.LAST\u TIME=A.Created\u TIME上加入TestingTable2 B
    其中B.产品标识A.项目标识
    联合所有
    选择*
    来自测试表1A
    A.BUYER\u ID=B.USER\u ID和B.PRODUCT\u ID=A.ITEM\u ID上的内部联接测试表2 B
    其中B.最后一次A.创建时间
    )X
    联合所有
    选择一个*,NULL,NULL,NULL
    来自测试表1A
    左外连接(
    
    SELECT A.BUYER_ID,A.ITEM_ID,CREATED_TIME,COALESCE(B.USER_ID,X.USER_ID,Y.USER_ID),
    COALESCE(B.PRODUCT_ID,X.PRODUCT_ID,Y.PRODUCT_ID)
    ,COALESCE(B.last_time,X.last_time,Y.last_time)
    FROM TestingTable1 A
    LEFT JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.PRODUCT_ID = A.ITEM_ID
    AND B.last_time = A.Created_TIME
    LEFT JOIN( SELECT USER_ID,PRODUCT_ID, last_time
      FROM TestingTable1 A
      LEFT JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.last_time = A.Created_TIME 
      WHERE  ISNULL(B.PRODUCT_ID,0) <> A.ITEM_ID AND B.USER_ID IS NOT NULL) X ON
      X.USER_ID = A.BUYER_ID AND A.Created_TIME = X.last_time
    LEFT JOIN( SELECT USER_ID,PRODUCT_ID, last_time
    FROM TestingTable1 A
    LEFT JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND ISNULL( B.PRODUCT_ID,0) =   A.ITEM_ID  
    WHERE  B.last_time <> A.Created_TIME AND B.USER_ID IS NOT NULL) Y ON
    A.BUYER_ID = Y.USER_ID AND A.ITEM_ID = Y.PRODUCT_ID