Double Not Exists SQL 逻辑解释

Double Not Exists SQL Logic Explanation

有 2 个表,一个叫 drinkers,有一列名字,另一个叫 frequents,有 2 个列,drinker 和 bar(他们常去)。

我有一个查询可以回答此语句:

Drinkers who frequent all bars 

或措辞不同:

Drinkers such that there aren’t any bars that they don’t frequent

现在这是结果查询:

SELECT d.name
FROM drinkers d
WHERE NOT EXISTS (
    SELECT b.name
    FROM bars b
    WHERE NOT EXISTS (
        SELECT *
        FROM frequents f
        WHERE f.drinker = d.name
        AND f.bar = b.name
        )
       )

当使用两个 NOT EXISTS 时,我很难遵循逻辑。 如果有人可以引导我了解如何理解这些类型的查询,将不胜感激。谢谢。

您可以尝试从内到外展开此类查询。所以,从最后一个子查询开始:

SELECT *
FROM frequents f
WHERE f.drinker = d.name
AND f.bar = b.name

在这里,您 select 正在寻找具有特定名称的特定酒吧的客户:换句话说,您正在检查这个特定的饮酒者是否去这个酒吧。所以现在:

SELECT b.name
FROM bars b
WHERE NOT EXISTS (
    SELECT *
    FROM frequents f
    WHERE f.drinker = d.name
    AND f.bar = b.name
)

可以看作是

SELECT b.name
FROM bars b
WHERE NOT EXISTS (this particular client in it)

这里是 select 所有没有此人作为客户的酒吧。因此,你最终会得到类似

SELECT d.name
FROM drinkers d
WHERE NOT EXISTS (any bar without this guy as a client)

而且我认为在这一点上查询应该看起来很清楚:select 没有他们就没有酒吧的所有饮酒者。

我不知道你是否绝对需要经历那些 NOT EXISTS 循环,因为你完全可以做这样的事情

SELECT d.name
FROM drinkers d 
INNER JOIN frequents f ON f.drinkerName = d.name
GROUP BY d.name
HAVING COUNT(distinct barName) = 
    (SELECT COUNT(distinct barName) 
     from frequents
)

基本上,您计算酒吧的总数,然后将每个人经常光顾的酒吧数量与该数量进行比较。在 COUNT 中添加那些 distinct 子句可以让您忽略重复项。