2012-07-11 27 views
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 

我需要比較TestingTable2TestingTable1BUYER_IDUSER_ID。我需要看到,如果BUYER_IDUSER_ID得到匹配的話,我需要與PRODUCT_IDCREATED_TIMELAST_TIME比較ITEM_ID,如果有與TestingTable1在他們或他們兩人中的任何一個進行比較後TestingTable2不匹配的話,我需要證明結果。

所以,如果你看一下上面的示例 - 我有三個方案基本

  1. Firstly-在TestingTable1,在第一行ITEM_ID不是TestingTable2第一行與PRODUCT_ID匹配,但CREATED_TIME與匹配LAST_TIME兩者的表中的第一行
  2. Secondly-在TestingTable1,在第二行中CREATED_TIME沒有的TestingTable2第二行中與LAST_TIME匹配但ITEM_ID與匹配對於第二行中兩個表
  3. Thirdly-在TestingTable1,在第三行中ITEM_ID不與PRODUCT_ID匹配並且還CREATED_TIME不與LAST_TIME匹配,所以第三行中兩者不與TestingTable1第三匹配行。

所以這三種情況我需要覆蓋,而總是比較TestingTable2TestingTable1TestingTable1是主表,通過它,總是需要進行比較,所以它意味着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,我排序(ORDER BY)由BUYER_IDCREATED_TIME和同樣與TestingTable2我與USER_IDLAST_TIME排序表,我通過確保數據做比較,屬於BUYER_IDUSER_ID上給定的一天。

回答

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 Fiddle

+0

感謝Mikael提供的詳細解決方案。我發佈了另一個類似的問題,在這個問題中,我需要使用我寫的查詢來實現我的第三個場景,因爲我的查詢正在爲所有這兩種場景工作,我只需要爲第三種場景修改它。還有第三個場景問題,我之前沒有問過。 [http://stackoverflow.com/questions/11464273/multi-join-in-a-single-sql-query](http://stackoverflow.com/questions/11464273/multi-join-in-a-single- SQL查詢)。任何幫助將不勝感激。 – ferhan 2012-07-13 05:49:01

0

你可以在TestingTable2每一個可能不匹配的行匹配TestingTable1所有行,而不在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 
+0

我已經更新了,我最初是想用幾個指針的問題。 – ferhan 2012-07-11 09:01:44

+0

感謝lc.for詳細的解決方案。我發佈了另一個類似的問題,其中我需要實現第三個場景,第三個場景完全不同於我的上述問題,並且需要使用我寫的查詢來實現第三個場景,因爲我的查詢正在爲所有這兩種場景工作,只需要修改它的第三種情況。還有第三個場景問題,我之前沒有問過。 [http://stackoverflow.com/questions/11464273/multi-join-in-a-single-sql-query](http://stackoverflow.com/questions/11464273/multi-join-in-a-single- SQL查詢)。任何幫助將不勝感激。 – ferhan 2012-07-13 05:50:14

0

有與整個嘗試的一個主要問題。

由於用戶ID/BuyerID是每一行中的相同,該查詢從TestingTable1比較每行從TestingTable2每一行

只有巧合的是,前兩種比較適合你;
如果您有幾行具有相似CREATED_TIME的行(即使使用不同的ITEM_ID),它們也會相互比較。

我推薦的是這樣的:
爲每個表添加primary key,並且將連接它們的foreign key
通過這種方式,您將能夠將TestingTable1中的每一行與TestingTable2中的等效內容進行比較,而不會產生「笛卡爾積」。

+0

我已經用幾個指針更新了我的問題,我最初的想法是什麼。 – ferhan 2012-07-11 08:51:55

+0

@rjchar你是說第三種情況只在同一天檢查差異嗎? – 2012-07-11 09:27:03

+0

所有這三種情況都將在特定的一天進行檢查。首先,我將在'BUYER_ID'和'CREATED_TIME'上對給定日期的'Table1'進行排序,並且'Table1'中每個'BUYER_ID'只有5個條目。同樣,我會在'USER_ID'和'LAST_TIME'上對給定日期的'Table2'進行排序,並且'Table2'中每個'USER_ID'只有5個條目。然後我會在兩張桌子上進行比較,因爲所有事情都會按時間進行排序,然後我可以進行比較。 – ferhan 2012-07-11 18:14:59

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 
     ) 

Live example at SQL Fiddle.

+0

雖然這並沒有做任何事情來關聯這兩個表,這是我認爲OP想要的。 – 2012-07-11 08:44:26

+0

當我試圖打開它時,SQL小提琴有問題。 – ferhan 2012-07-11 08:52:36

+0

@rjchar - 你有什麼樣的麻煩?你用什麼瀏覽器? (我是SQL Fiddle BTW的擁有者) – 2012-07-11 15:28:04