我有两张桌子:
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'
的变体。
答案 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