如何跳过外连接中的匹配记录?

时间:2014-08-12 07:32:37

标签: sql oracle

我有一个场景,我希望在外连接表中跳过与特定产品匹配的记录。我的查询中缺少什么?还有什么我必须在我的where子句中提到以实现所需的查询。

Customer_Profile表。

 USER_ID        
 110            
 111    
 112
 113
 114

服务表。

 USER_ID            PRODUCT_NAME
 110                'Daily Offer'
 119                'Daily Offer'
 120                'Daily Offer'
 110                'Another Offer'

必需的结果集。如果110选择“每日优惠”,我只想跳过它。如果110选择了另一个要约,它将成为所需结果集的一部分。

 111    
 112
 113
 114

我试过查询:

SELECT C.USER_ID FROM CUSTOMER_PROFILE C 
LEFT OUTER JOIN SERVICES S ON C.USER_ID = S.USER_ID
WHERE (S.PRODUCT_NAME <> 'Daily Offer' or S.PRODUCT_NAME is NULL)

给出以下输出。如何跳过110个用户ID?

 110
 111    
 112
 113
 114

4 个答案:

答案 0 :(得分:1)

为什么不这个

SELECT C.USER_ID 
FROM CUSTOMER_PROFILE C 
WHERE C.USER_ID NOT IN( SELECT S.USER_ID
                        FROM SERVICES S 
                        WHERE S.PRODUCT_NAME = 'Daily Offer' OR S.PRODUCT_NAME is NULL
                        GROUP BY S.USER_ID   
                        HAVING COUNT(S.USER_ID) = 1
                      )

<强> FIDDLE DEMO

答案 1 :(得分:1)

我认为这是你真正想要的:

SELECT C.USER_ID,s.* 
FROM CUSTOMER_PROFILE C 
LEFT OUTER JOIN SERVICES S 
ON C.USER_ID = S.USER_ID and S.PRODUCT_NAME <> 'Daily Offer'
WHERE  S.PRODUCT_NAME is NULL

使用s.*查看您的代码与我的代码之间的区别。

Sql Fiddle here

答案 2 :(得分:0)

只需将连接更改为不等于:

SELECT C.USER_ID 
FROM CUSTOMER_PROFILE C 
LEFT OUTER JOIN SERVICES S ON C.USER_ID <> S.USER_ID
OR (C.USER_ID = S.USER_ID AND S.PRODUCT_NAME <> 'Daily Offer')

答案 3 :(得分:0)

SELECT C.USER_ID
FROM CUSTOMER_PROFILE C
LEFT OUTER JOIN (
    SELECT MAX(PRODUCT_NAME = 'Daily Offer') has_offer, USER_ID
    FROM SERVICES GROUP BY USER_ID
) S ON C.USER_ID = S.USER_ID WHERE has_offer = 0 OR has_offer IS NULL;
当且仅当用户至少有一个每日优惠时,每位用户<MAX(PRODUCT_NAME = 'Daily Offer')才会True,我相信这正是您想要的。

编辑:但是,如果用户有多个优惠,则只会打印一次。您可以通过稍微调整查询来多次打印:

SELECT C.USER_ID
FROM CUSTOMER_PROFILE C
LEFT OUTER JOIN (
    (
        SELECT MAX(PRODUCT_NAME = 'Daily Offer') has_offer, USER_ID
        FROM SERVICES GROUP BY USER_ID
    ) F
    INNER JOIN SERVICES S
    ON F.USER_ID = S.USER_ID
) ON C.USER_ID = S.USER_ID
WHERE F.has_offer = 0 OR F.has_offer IS NULL;