1

2 つのテーブルがあるこの複数結合の問題に頭を悩ませようとしています。

INTERESTED_IN
email           item
-----------------------
bob@email.com   widgetA
karen@email.com widgetA
karen@email.com widgetB
sue@email.com   widgetC
tony@email.com  widgetA
tony@email.com  widgetB
tony@email.com  widgetC


PURCHASED
email           item
-----------------------
bob@email.com   widgetA
karen@email.com widgetA
tony@email.com  widgetB
julie@email.com widgetC

目的: Interesting_inテーブルと purchase テーブルに存在する人のメールとアイテムを返しますが、purchased テーブルには存在しないアイテムのみを返します。したがって、結果のテーブルは次のようになります

email           item
-----------------------
karen@email.com widgetB
tony@email.com  widgetA
tony@email.com  widgetC

概念的にはこれを行う方法を知っていますが、データセットが非常に大きくなる可能性があるため、これを行う最も効率的な方法に頭を悩ませています。誰かがこれを行うための最良の方法について教えてくれますか?

ありがとう!


アップデート

SELECT email, item
FROM (
    SELECT i.email, i.item
    FROM interested_in i
    INNER JOIN purchased  p ON i.email = p.email
    ) 

MINUS

SELECT email, item
FROM purchased 
4

4 に答える 4

2

ああ、スーが恋しかった。INTERESTED_INしたがって、メールがテーブルに存在するテーブルのすべての行が必要ですが、とPURCHASEDの両方がテーブルに存在する行は必要ありません。 EMAILITEMPURCHASED

最も明白なアプローチはこのようなものですが、PURCHASEDテーブルを 2 回ヒットする必要があります。

SELECT email, item
  FROM interested_in i
 WHERE EXISTS( SELECT 1
                 FROM purchased p
                WHERE i.email = p.email )
   AND NOT EXISTS( SELECT 1
                     FROM purchased p
                    WHERE i.email = p.email
                      AND i.item  = p.item )

また

SELECT email, item
  FROM interested_in i
 WHERE EXISTS( SELECT 1
                 FROM purchased p
                WHERE i.email = p.email )
MINUS
SELECT email, item
  FROM purchased

私は、テーブルに 1 度しか着手せずにこれを行う賢い方法があることに強く賭けたいと思いPURCHASEDますが、そのようなアプローチはすぐにはわかりません。

于 2012-07-06T21:00:37.713 に答える
1

おそらく上記よりも優れていません...

select
  a.*
from
  interested_in a
  inner join (
    select distinct
      x.email
    from 
      interested_in x
      inner join purchased y
        on x.email = y.email
    ) valid_emails
    on valid_emails.email = a.email 
  left join purchased b
    on a.email = b.email
    and a.item = b.item
where
  b.email is null
;

結果:

EMAIL           ITEM
tony@email.com  widgetA
tony@email.com  widgetC
karen@email.com widgetB
于 2012-07-07T00:22:58.100 に答える
0

興味のあるテーブルからすべてを選択し、左結合を使用して人々がすでに購入したアイテムを除外する必要があります。

select * from 
   INTERESTED_IN I left join PURCHASED P 
   on I.EMAIL=P.EMAIL and I.ITEM=P.ITEM
where P.EMAIL is null

上記のクエリを表す中間テーブルは次のとおりです。

I.EMAIL         I.ITEM   P.EMAIL         P.ITEM
------------------------------------------------
bob@email.com   widgetA  bob@email.com   widgetA
karen@email.com widgetA  karen@email.com widgetA
karen@email.com widgetB  
sue@email.com   widgetC
tony@email.com  widgetA
tony@email.com  widgetB  tony@email.com  widgetB
tony@email.com  widgetC
于 2012-07-07T01:18:56.193 に答える
0

マイナスの方法はより効率的です。purchase.item が null である 3 番目の完全結合

于 2012-07-06T21:07:28.283 に答える