SQL查询 - 排除具有多个值的列的一个值匹配的行

时间:2014-06-01 02:04:48

标签: sql postgresql join left-join

我有一组表格如下。 (这有点简化,其中一些表有其他一些列,但我试图削减它)

Website
ID     |
_____________________________________

10001
10002
10003

Domain Names
Name                | Website_ID
_____________________________________
surfinglikewoah.com | 10001
surfinglikewoah.net | 10001
ihatesurfing.com    | 10002
surfinghatesme.net  | 10003 

Promotion Redemptions
Promo ID            | Website_ID 
_____________________________________
0001                | 10001
0002                | 10001
0003                | 10001
0002                | 10002


Promo Codes
Promo ID            | Code 
_____________________________________
0001                | test
0002                | super-discount
0003                | double-discount

我试图过滤任何有促销活动的帐户"测试" - 但是,由于这些网站与多次促销兑换相关联,因此错误的行仍会显示在我的搜索结果中。注意:我将根据其他条件进行过滤,同样使用每行可能有多个值的列,或者甚至可以为空。

到目前为止,这是查询:

select distinct
ws.id, 
ARRAY(select distinct dn.name FROM domainname dn WHERE ws.id = dn.website_id), 
ARRAY(select p.code FROM promotionredemption pr, promotion p WHERE p.id = pr.promotion_id        AND pr.site_id = ws.id) 

from website ws 
left join domainname dn on dn.website_id = ws.id
left join promotionredemption pr on pr.site_id = ws.id
left join promotion p on p.id = pr.promotion_id


where p.code != 'test'

order by 
   ws.id asc

此查询不应返回surflikewoah.com结果 - 但确实如此,因为该结果还有两个其他促销兑换不匹配' test'。

Results: 
10001 | {surfinglikewoah.com, surfinglikewoah.net} | {test, super-discount, double-discount}  
10002 | {ihatesurfing.com} | {super-discount} 
10003 | {surfinghatesme.net} | {} 

我觉得我错过了一些明显的东西!

非常感谢帮助。

2 个答案:

答案 0 :(得分:1)

您想要找到的是另一条记录不存在的记录。最后一句的最后两个单词是关键的NOT EXISTS。我发现很多使用外连接的代码,我认为使用EXISTS子句会更好。

以下查询可能并不完全符合您的要求,但希望它能让您足够接近,以便您可以调整它以确定您的确切需求。

 select ws.id
    ARRAY(select distinct dn.name FROM domainname dn WHERE ws.id = dn.website_id), 
    ARRAY(select p.code FROM promotionredemption pr, promotion p WHERE p.id = pr.promotion_id        AND pr.site_id = ws.id) 
 from   website ws
 where  not exists (
        select      1
        from        promotion p
        left join   promotionredemption pr
            on  p.id = pr.promotion_id      
        where       pr.site_id = ws.id
            and p.code = 'test'
    )
 order by
    ws.id asc

答案 1 :(得分:0)

ARRAY(选择p.code FROM promotionredemption pr,promotion p WHERE p.id = pr.promotion_id AND pr.site_id = ws.id)

将其更改为:

ARRAY(select p.code FROM promotionredemption pr, promotion pp 
      WHERE pp.id = pr.promotion_id        
       AND pr.site_id = ws.id
       AND PP.Id = P.ID)