如果这是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
我需要在TestingTable2
和TestingTable1
上将BUYER_ID
与USER_ID
进行比较。我需要看一下,如果BUYER_ID
和USER_ID
匹配,那么我需要将ITEM_ID
与PRODUCT_ID
和CREATED_TIME
与LAST_TIME
进行比较,如果有的话与TestingTable2
中的任何一个或两者中的TestingTable1
进行比较后,TestingTable1
不匹配,那么我需要显示结果。
因此,如果你看一下上面的例子 - 基本上我有三个场景
ITEM_ID
中,第一行PRODUCT_ID
与TestingTable2
的第一行中的CREATED_TIME
不匹配,但LAST_TIME
与{匹配} {1}}表示两个表中的第一行TestingTable1
中,第二行CREATED_TIME
与LAST_TIME
第二行中的TestingTable2
不匹配,但ITEM_ID
与{匹配} {1}}表示两个表中的第二行PRODUCT_ID
中,第三行TestingTable1
与ITEM_ID
不匹配且PRODUCT_ID
与CREATED_TIME
不匹配,因此在它们的第三行与LAST_TIME
第三行不匹配。因此,在将TestingTable1
与TestingTable2
进行比较时,我需要介绍这三种情况。 TestingTable1
是MAIN表,通过该表总是需要进行比较,这意味着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 Two
。我是否能够实现第三种情况而感到困惑?
Third 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
和BUYER_ID
对表进行排序(ORDER BY),与CREATED_TIME
相同,我正在使用{{1}进行排序}和TestingTable2
我正在进行比较,确保数据属于某一天的USER_ID
和LAST_TIME
。
答案 0 :(得分: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
)
答案 1 :(得分: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);
答案 2 :(得分:0)
您可以获得的最接近的是匹配TestingTable1
中的所有行,而TestingTable2
中的所有行与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 | LAST_TIME ---------+----------------+----------------------- 1345653 333333333333 2012-07-09 05:27:18
您的结果集如下所示:
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 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 | LAST_TIME ---------+----------------+----------------------- 1345653 110909316904 2012-07-09 19:57:33
答案 3 :(得分:0)
整个尝试都存在一个主要问题。
由于UserID / BuyerID在每一行都相同,因此查询会将来自TestingTable1的每一行与来自TestingTable2的每一行进行比较。
前两个比较对你有用,这只是巧合; 如果您有多个具有类似CREATED_TIME的行(即使具有不同的ITEM_ID),它们也会相互比较。
我建议的是:
为每个表添加primary key
,并为其添加foreign key
这样,您就可以将TestingTable1中的每一行与TestingTable2中的等效项进行比较,而不会产生“笛卡尔积”。