4

可能重复:
SQL Query JOIN with Table

如果这是 TestingTable1 中的数据

BUYER_ID  |   ITEM_ID       |  CREATED_TIME
----------+-----------------+----------------------
1345653      151851771618     2012-07-09 19:57:33
1345653      110909316904     2012-07-09 21:29:06
1345653      221065796761     2012-07-09 19:31:48

如果这是TestingTable2中的以下数据

USER_ID  |   PRODUCT_ID    |    LAST_TIME
---------+----------------+-----------------------
1345653     150851771618      2012-07-09 19:57:33
1345653     110909316904      2012-07-09 22:29:06
1345653     221165796761      2012-07-09 12:31:48

我需要TestingTable2TestingTable1onBUYER_ID和进行比较USER_ID。我需要看看,如果BUYER_IDUSER_ID匹配,那么我需要比较ITEM_ID和,如果在PRODUCT_ID与其中一个或两个比较之后存在不匹配,那么我需要显示结果。CREATED_TIMELAST_TIMETestingTable2TestingTable1

所以如果你看上面的例子——我基本上有三个场景

  1. 首先TestingTable1,在第一行与第一行ITEM_ID不匹配PRODUCT_IDTestingTable2CREATED_TIMELAST_TIME两个表中的第一行匹配
  2. 其次TestingTable1,在第二行中,第二行与第二行CREATED_TIME不匹配LAST_TIMETestingTable2ITEM_IDPRODUCT_ID两个表中的第二行匹配
  3. 第三 - 在TestingTable1中,在第三行ITEM_ID中不匹配,PRODUCT_ID也不CREATED_TIME匹配LAST_TIME,所以在第三行中,它们都与第三行不匹配TestingTable1

TestingTable2因此,这是我在与TestingTable1always进行比较时需要涵盖的三种情况。并且TestingTable1是需要始终进行比较的主表,因此这意味着其中的数据TestingTable1始终是准确的。

所以我需要考虑上面的例子来显示这样的结果,如果不匹配其中一个或两个 -TestingTable1数据然后在它旁边是相同的TestingTable2数据,这样我就可以看到与之TestingTable1相比有什么值TestingTable2

BUYER_ID   |   ITEM_ID       |    CREATED_TIME           |      USER_ID   |     PRODUCT_ID     |     LAST_TIME   
-----------+-----------------+---------------------------+----------------+--------------------+-----------------------
1345653        151851771618       2012-07-09 19:57:33           1345653        150851771618         2012-07-09 19:57:33
1345653        110909316904       2012-07-09 21:29:06           1345653        110909316904         2012-07-09 22:29:06
1345653        221065796761       2012-07-09 19:31:48           1345653        221165796761         2012-07-09 12:31:48

所以我写了一个查询,我认为它会涵盖我所有的三个场景,但只有它涵盖First TwoThird One. 我很困惑我们是否可以实现第三种情况?

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.PRODUCTID <> A.ITEM_ID
    UNION ALL
    SELECT * 
    FROM TestingTable1 A
    INNER JOIN TestingTable2 B ON A.BUYER_ID = B.USER_ID AND B.PRODUCTID = A.ITEM_ID  
    WHERE B.t1time <> A.Created_TIME  
 ) X    

任何建议将不胜感激。

更新:-

只是快速更新我最初想做的事情。因为我知道我的第三种情况很少有问题。

首先在 中TestingTable1,我按和排序(ORDER BY)表,我用BUYER_ID和排序,我通过确保数据属于和在给定日期进行比较。CREATED_TIMETestingTable2USER_IDLAST_TIMEBUYER_IDUSER_ID

4

4 回答 4

1

您可以使用non exists子句在一个表中查找在另一个表中不匹配的行。您可以对union另一个表重复此操作:

select  'missing in t2', *
from    TestingTable1 t1
where   not exists
        (
        select  *
        from    TestingTable2 t2
        where   t1.buyer_id = t2.user_id
                and t1.item_id = t2.product_id
                and t1.created_time = t2.last_time
        )
union all
select  'missing in t1', *
from    TestingTable2 t2
where   not exists
        (
        select  *
        from    TestingTable1 t1
        where   t1.buyer_id = t2.user_id
                and t1.item_id = t2.product_id
                and t1.created_time = t2.last_time
        )

SQL Fiddle 上的实时示例。

于 2012-07-11T08:43:18.503 回答
1
with C as
(
  select *
  from TestingTable1 A
    inner join TestingTable2 B
      on A.BUYER_ID = B.USER_ID and
         B.LAST_TIME = A.Created_TIME and
         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 and
         B.LAST_TIME <> A.CREATED_TIME
)
select *
from C
union all
select *
from TestingTable1 A
  inner join TestingTable2 B
    on A.BUYER_ID = B.USER_ID and
       A.CREATED_TIME <> B.LAST_TIME and
       A.ITEM_ID <> B.PRODUCT_ID
where not exists (select *
                  from C
                  where A.BUYER_ID = C.BUYER_ID and
                        A.ITEM_ID = C.ITEM_ID and
                        A.CREATED_TIME = C.CREATED_TIME) and
      not exists (select *
                  from C
                  where B.USER_ID = C.USER_ID and
                        B.PRODUCT_ID = C.PRODUCT_ID and
                        B.LAST_TIME = C.LAST_TIME);

SQL小提琴

于 2012-07-11T08:49:55.073 回答
0

整个尝试存在一个主要问题。

因为每一行的 UserID/BuyerID 都是相同的,所以查询会将TestingTable1 中的每一行TestingTable2 中的每一行进行比较。

前两个比较对您有用只是巧合。
如果您有几行具有相似的 CREATED_TIME(即使具有不同的 ITEM_ID),它们将被相互比较。

我推荐的是:为每个表
添加一个,然后将它们连接起来。 这样,您将能够将 TestingTable1 中的每一行与 TestingTable2 中的对应行进行比较,而不会产生“笛卡尔积”。primary keyforeign key

于 2012-07-11T08:35:02.017 回答
0

您可以获得的最接近的方法是将 in 中TestingTable1没有匹配的所有行与 inTestingTable2所有可能不匹配的行匹配TestingTable2

像这样(未经测试,但希望你明白):

SELECT *
FROM TestingTable1 AS T1
INNER JOIN TestingTable2 AS T2 ON T1.BUYER_ID = T2.USER_ID
    AND
    (
        (
            (T1.ITEM_ID = T2.PRODUCT_ID AND T1.CREATED_TIME <> T2.LAST_TIME)
            OR (T1.ITEM_ID <> T2.PRODUCT_ID AND T1.CREATED_TIME = T2.LAST_TIME)
            OR 
            (
                T1.ITEM_ID <> T2.PRODUCT_ID AND T1.CREATED_TIME <> T2.LAST_TIME
                AND NOT EXISTS(SELECT 1
                       FROM TestingTable2 AS T2a
                       INNER JOIN TestingTable1 AS T1a ON T2a.USER_ID = T1a.BUYER_ID
                       AND 
                       (
                           (T1a.ITEM_ID = T2a.PRODUCT_ID AND T1a.CREATED_TIME <> T2a.LAST_TIME)
                           OR (T1a.ITEM_ID <> T2a.PRODUCT_ID AND T1a.CREATED_TIME = T2a.LAST_TIME)
                       )
                       WHERE T1a.BUYER_ID = T1.BUYER_ID
                       AND (T2a.PRODUCT_ID <> T2.PRODUCT_ID OR T2a.LAST_TIME <> T2.LAST_TIME)                       
                      )
            )
        )
    )

也就是说,如果你有一个额外的行TestingTable2

USER_ID | PRODUCT_ID | 上次
---------+----------------+------------------------
1345653 333333333333 2012-07-09 05:27:18

您的结果集如下所示:

BUYER_ID | 项目 ID | 创建_TIME | USER_ID | PRODUCT_ID | 上次   
-----------+-----------------+-------- --------+----------------+--------+---- ------------------
1345653 151851771618 2012-07-09 19:57:33 1345653 150851771618 2012-07-09 19:57:33
1345653 110909316904 2012-07-09 21:29:06 1345653 110909316904 2012-07-09 22:29:06
1345653 221065796761 2012-07-09 19:31:48 1345653 221165796761 2012-07-09 12:31:48
1345653 221065796761 2012-07-09 19:31:48 1345653 333333333333 2012-07-09 05:27:18

请注意,这一切都假设您对于每个错误的 PRODUCT_ID 或 LAST_TIME都有一个且只有一个相关行。TestingTable2否则你会得到各种疯狂的笛卡尔积匹配!为了避免这种情况,您需要确定一个或两个表的排序,以确定应首先匹配哪一行。

例如,尝试将满足方案 1 和 2 的以下行添加到TestingTable2并查看会发生什么:

USER_ID | PRODUCT_ID | 上次
---------+----------------+------------------------
1345653 110909316904 2012-07-09 19:57:33
于 2012-07-11T08:32:55.093 回答