【问题标题】:SQL Query - excluding rows where one value of a column with multiple values matchesSQL 查询 - 排除具有多个值的列的一个值匹配的行
【发布时间】:2014-06-01 02:04:47
【问题描述】:

我有一组如下表。 (这有点简化,其中一些表还有一些其他列,但我已经尝试减少它)

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

此查询不应返回 surfinglikewoah.com 结果 - 但它确实返回了,因为该结果还有另外两个与“测试”不匹配的促销兑换。

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

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

非常感谢您的帮助。

【问题讨论】:

  • 执行一组差异:从不匹配'test'的结果集中减去匹配'test'的结果集。在 SQL Server 中使用 EXCEPT 运算符,如 SELECT ... EXCEPT SELECT ....
  • 谢谢 pieter,我正在进一步研究 except 运算符......尽管我也在寻求下面的 NOT EXISTS 建议答案。
  • 此链接解释了如何使用 LEFT JOIN 在 SQL 中执行 EXCEPT(或 MINUS)操作:gokhanatil.com/2010/10/minus-and-intersect-in-mysql.html

标签: sql postgresql join left-join


【解决方案1】:

您要查找的是一条记录,而另一条记录不存在。最后一句话的最后两个词是关键不存在。我发现很多使用外连接的代码,我认为使用 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

【讨论】:

  • 我想这可能有我需要的金块,谢谢。虽然目前我正在失去 10002 | {ihatesurfing.com} |我的结果中的 {super-discount}。它确实过滤掉了带有“测试”的行,但我得到的唯一结果是带有“空”促销的那个..
  • 知道了!在您建议的示例中只是一个小错字:并且 p.code != 'test' 应该是并且 p.code = 'test' 因为 NOT 已经在 NOT 中指定了存在。我当然知道你很快就把它扔在一起了。现在可以了!非常感谢。
  • 现在在代码中修复了这个问题。感谢您让我知道这一点。
【解决方案2】:

数组(从promotionredemption pr中选择p.code,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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-29
    • 2017-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多