sql - 将嵌套的(二)NOT IN转换成嵌套的(二)NOT Exists
问题描述
试图NOT EXISTS
更好地理解。即使在嵌套情况下,NOT EXISTS
我们也可以随时替换吗?NOT IN
我发现了这个类似的问题NOT IN
,它在尝试处理嵌套案例时只有一个。我们有两个表,已注册和 preActivity。
Registered 有 mId(string)、aId(string)、Quarter(string)、year(integer) 和 preActivity 有 aId(string)、preAId(string) 其中
> mId is member id,
> aId is the activity Id,
> preAId is the prerequisite activity Id.
如果我们有这个带有嵌套 NOT IN 的查询,以找出所有成员在 YMCA 游泳活动(课程)之前已经注册了所有必需的活动(先决条件)课程。我们可以将它转换为两个嵌套的 NOT EXIST 吗?
SELECT DISTINCT r.mid
FROM registered r
WHERE r.mid NOT IN (SELECT r.mid
FROM preActivity p
WHERE p.aid = "swimming" AND
p.preAId NOT IN (SELECT r2.mid
FROM registered r2
WHERE r2.mid = r.mid));
使用这篇文章的提示,我们可以转换其中一个 NOT IN,但第二个需要我几个小时。有人可以帮忙解释一下吗?
这是我到目前为止所拥有的:
SELECT DISTINCT r.mid
FROM registered r
WHERE NOT EXISTS (SELECT r.mid
FROM preActivity p
WHERE p.aid = "swimming" AND
p.preAId NOT IN (SELECT r2.mid # how can we compare p.preAId with some rows selected from r2 Notice we don't have preAid field from resistered table (following the idea from the post?
FROM registered r2
WHERE r2.mid = r.mid));
或者我们不能在这里应用相同的想法,因为它是一个两个嵌套的案例?
解决方案
首先要记住:查询中SELECT
的[NOT] EXISTS
无关紧要,因为我们只是在寻找行的存在。你甚至可以写SELECT 1/0
而不出错。所以大部分人都会写[NOT] EXISTS (SELECT 1
。(我喜欢将所有内容放在一行上,而将其余的子查询放在新行上)
其次,NOT IN
查询可能有围绕空列的问题,所以最好总是写 a NOT EXISTS
。
现在,如果您分析[NOT] IN
查询,您将看到半连接位于之前的列上,而SELECT
. 所以一个查询:
X.colA [NOT] IN
(SELECT Y.colA FROM Y)
总是可以转换为
[NOT] EXISTS (SELECT 1
FROM Y
WHERE Y.colA = X.colA)
另一个有趣的语法,对多列连接或可为空的列最有用,是:
[NOT] EXISTS (
SELECT X.colA
INTERSECT
SELECT Y.colA
FROM Y)
不要忘记始终在子查询列上使用正确的表别名,如果您弄错了,那么您的查询可能会在您不注意的情况下返回不正确的结果。
例如,这里发生了什么?
[NOT] EXISTS (SELECT 1
FROM Y
WHERE X.colA = colA)
在您的情况下,您的第一个NOT IN
查询有点奇怪。
你正在r.mid
加入的两边,所以实际上这变成了一个EXISTS
无论如何。
因此,您的查询可以重写为:
select distinct r.mid
from registered r
where not exists (select 1
From preActivity p
where p.aid = "swimming" and
not exists (select 1
From registered r2
where r2.mid = r.mid and r2.mid = p.preAId
)
);
推荐阅读
- symfony - 无法使用多个提供商和防火墙注销 Symfony 5
- selenium - 无法通过 xpath 索引(硒)获取元素
- javascript - 方法 map() - 一次从后端数组获取所有对象值
- user-interface - 我的 Oculus 耳机干扰了我的 UI 滚动。我的光线交互器可以工作,但头显的移动也可以控制滚动
- google-apps-script - OnSelectionChange 与 SpreadsheetApp.getUI().alert("Message") 不一致 - Google Apps 脚本
- dataframe - 如何将内联数据集(增量)的参数化链接服务的参数传递给数据流?
- bash - 如何在 CMake 生成的 Makefile 中编译所有目标的子集,这些目标以 bash for 循环中的给定前缀开头
- node.js - 创建与 MongoDB 日期一起使用的自定义 GraphQLDateTime 标量
- reactjs - 用不同的值在 Mongoose 中更新多个文档——Express Js
- vba - 如何在 VBA 的 Access 表中为日期时间字段分配值?