在集合中选择无

时间:2015-10-08 17:19:06

标签: mysql sql

我有两张桌子:

Invariant (UniqueID, characteristic1, characteristic2)
Variant   (VariantID, UniqueID, specification1, specification2)

每个项目在实现之间都有自己不变的特征。每个实现也都有自己的独立属性。

因此,我使用这样的查询来查找具有给定特征和规范的项目:

SELECT * 
FROM `Invariants` 
LEFT JOIN (`Variants`) ON (`Variants`.`UniqueID`=`Invariants`.`UniqueID`)   
WHERE char2='y' and spec1='x' 
GROUP BY `Invariant`.`UniqueID`;

我正在寻找一个将返回所有从未满足给定规范的项目的查询。因此,如果项目100的变体之一具有spec1='bad',那么我不希望包含项目100,无论它是否具有spec1='good'的变体。

1 个答案:

答案 0 :(得分:0)

select *
from Invariants iv
where not exists (
    select 1
    from Variants v
    where v.UniqueId = iv.UniqueId and v.spec1 = 'bad'
)

下面的查询没有解决您的问题,我可能会快速阅读并认为您只想获取特定类型的不变属性。但我会注意到你不应该使用左连接,然后在where子句中对右表中的列进行过滤(除了检查空值)。人们总是犯这个错误,乍看之下就是这个错误。

左连接的整个目的是某些行不匹配,因此在右侧表的列中将具有填充空值。首先发生此连接逻辑,然后应用where子句。当您有where spec1 = 'x'之类的条件时,它将始终根据空值计算为false。所以你最终会删除你想要保留的所有行。

使用这些不变/自定义值表会发生这种情况。您只对其中一个属性感兴趣,但如果您在加入之前或在加入条件之内没有过滤,则最终会丢弃行,因为该值并不存在且您没有这样做。一旦尝试在属性名称上应用where - 子句条件,就会有一个值进行比较。

希望有道理。请参阅下面的示例:

select iv.UniqueId, ...
from
    Invariants iv left outer join
    Variants
        on v.UniqueId = vi.UniqueId and v.spec1 = 'x'

select iv.UniqueId, ...
from
    Invariants iv left outer join
    (    
        select
        from Variants
        where spec1 = 'x'
    ) v
        on v.UniqueId = vi.UniqueId