问题描述
我有两个表,它们的外观大致如下:
类别:
+----+-----------+--------+----------------+ | id | entity_id | set_id | type | +----+-----------+--------+----------------+ | 1 | 49 | 1 | signup | | 2 | 57 | 1 | signup | | 3 | 65 | 1 | signup | | 4 | 69 | 1 | recommendation | | 5 | 73 | 1 | signup | | 6 | 77 | 1 | recommendation | | 7 | 23 | 2 | comment | | 8 | 45 | 2 | recommendation | | 9 | 56 | 2 | signup | | 10| 76 | 2 | signup | +----+-----------+--------+----------------+
步骤:
+----+--------+----------+--------+ | id | set_id | start_id | end_id | +----+--------+----------+--------+ | 1 | 1 | 49 | 57 | | 2 | 1 | 57 | 65 | | 3 | 1 | 65 | 69 | | 4 | 1 | 69 | 73 | | 5 | 1 | 77 | 57 | | 6 | 2 | 23 | 45 | | 7 | 2 | 45 | 56 | | 8 | 2 | 56 | 76 | +----+--------+----------+--------+
我需要从set_id
中选择给定categories
的行,但前提是必须在entity_id
列的steps
中找到start_id
的行,但不是end_id
列。
因此在此示例中,这些是我希望返回的两条记录:
+----+-----------+--------+----------------+ | id | entity_id | set_id | type | +----+-----------+--------+----------------+ | 1 | 49 | 1 | signup | | 6 | 77 | 1 | recommendation | +----+--------+----------+-----------------+
我知道如何在set_id
上执行基本联接,但是我不确定如何从set_id
中搜索该steps
的所有记录,并排除那些具有{ entity_id
类似的东西:
end_id
该逻辑应如何正确形成?
解决方法
现有逻辑在这里运作良好,也很简单:
SELECT c.*
FROM categories c
WHERE
EXISTS (SELECT 1 FROM steps s WHERE s.set_id = c.set_id AND c.entity_id = s.start_id)
AND
NOT EXISTS (SELECT 1 FROM steps s WHERE s.set_id = c.set_id AND c.entity_id = s.end_id);
上面的查询用普通英语阅读,它表示要查找所有类别记录,以便在steps
中有一个匹配记录,其中entity_id
与start_id
匹配,但是确实有 not 在steps
中还存在一条记录,其中entity_id
出现在end_id
中。