1

我试图解决这个多连接问题,我有两个表

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

目标:返回存在于interested_in 表和购买表中的人的电子邮件和项目,但只返回不在购买表中的项目。所以结果表会像这样

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而不是表中同时存在EMAIL和的行。 ITEMPURCHASED

最明显的方法是这样的,尽管它需要PURCHASED两次击球。

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

我强烈打赌有一个聪明的方法可以做到这一点,而只打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

减法应该更有效。第三种方式完全加入其中购买。项目为空

于 2012-07-06T21:07:28.283 回答
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 回答