mysql - 选择没有任何特定 Bar 事件的 Foo 对象

标签 mysql sql join group-by having

考虑两个表:

Foo:
  id INT,
  name VARCHAR

Bar:
  id INT,
  foo_id INT REFERENCES Foo(id),
  event_type VARCHAR DEFAULT NULL,
  event_duration INT DEFAULT NULL

每个 Foo 项目可以有多个 Bar 事件。 如何查询没有满足以下任一条件的 Bar 事件的 Foo 项目:

  1. event_type 不是以下值之一:'miss'、'scratch'、'scrape'
  2. event_duration 不为空

例如,考虑:

Foo id=1:
    event_type: hit       | event_duration: NULL
    event_type: poke      | event_duration: NULL
    event_type: capture   | event_duration: NULL

Foo id=2:
    event_type: hit       | event_duration: 2
    event_type: poke      | event_duration: NULL
    event_type: capture   | event_duration: NULL

Foo id=3:
    event_type: miss      | event_duration: NULL
    event_type: poke      | event_duration: NULL
    event_type: capture   | event_duration: NULL

Foo id=4:
    event_type: strike    | event_duration: NULL
    event_type: hit       | event_duration: NULL
    event_type: land      | event_duration: NULL

只应返回具有 id=1id=4 的 Foo 项。不应返回带有 id=2 的项目,因为它的 event_duration 之一不是 NULL。 id=3 的项目不应返回,因为它的 event_type 之一是 miss(在禁止的 event_types 列表中)。

我尝试了来自this terrific answer的各种想法,它响应了我希望从中学到足够的知识以构建此查询的情况的概括。 las,我一直无法概括足以解决此问题的答案。这是一个无效查询的例子,还有很多其他失败的尝试:

SELECT
    f.name
FROM
    Foo f JOIN Bar b ON f.id = b.foo_id
GROUP BY
    b.event_type, b.event_duration
HAVING
    b.event_type not in ('miss', 'scratch', 'scrape')
  AND
    b.event_duration not null

这是另一个无效的查询:

SELECT
    f.name
FROM
    (
    SELECT
        f.name, b.event_duration
    FROM
        Foo f JOIN Bar b ON f.id = b.foo_id
    GROUP BY
        b.event_type
    HAVING
        b.event_type not in ('miss', 'scratch', 'scrape')
    )
GROUP BY
    b.event_duration
HAVING
    b.event_duration not null

还有许多其他不工作的查询,其中包含关于 JOIN 和子查询的一些想法。 请注意,Foo 表有近 500 万行,Bar 表有近 200 万行。这些表在相关字段上建立了索引,但是 O(n^2) 在这些大表上根本不可能。

最佳答案

您可以使用NOT EXISTS 来获得您想要的结果。

SELECT f.name
FROM foo f
WHERE NOT EXISTS (SELECT 1 FROM bar b
                  WHERE b.foo_id = f.id
                  AND (b.event_type IN ('miss','scratch','scrape')
                       OR b.event_duration IS NOT NULL)
                  )

关于mysql - 选择没有任何特定 Bar 事件的 Foo 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21366599/

相关文章:

php - 为什么php无法打印mysql数据库的数据?

javascript - jQuery - 获取元素的 ID,如果它等于值,则添加链接

mysql - MySQL中字符串出现次数排名

mysql - 如何使用 JOIN 而不是子查询(NOT IN)

sql - 如何组合 SELECT 语句来计算 SQL Server 中的百分比、成功和失败?

MySQL 触发器 - 使用从另一个表获取的平均值更新表中的最后一行

javascript - 使用 Threejs 将彩色线条加载到浏览器中

php - 根据文件扩展名和带超链接的文件数显示从 MySQL 上传的文件

c# - 在 C# WinForm 控件(文本框、组合框、标签)中显示 SQL 数据库中的数据

MySQL JOIN 两次查找