sql - SQL“IN”子句使用同时包含/排除项目?
问题描述
我想就解决特定修订的最佳方式获得一些帮助。我有以下 SQL 查询:
SELECT * FROM PRODDTA.F4105
WHERE (COITM, COMCU) IN ((`"Set of Data 1"`))
AND (COLOCN, COLEDG) NOT IN ((`"Set of Data 2"`));
我想要做的是修改是否有办法将这些项目合并为一个:
SELECT * FROM PRODDTA.F4105
WHERE (COITM, COMCU, COLOCN, COLEDG) IN ((`"Set of Data 1 & 2"`));
你知道这是否可以实现吗?
非常感谢提前,
解决方案
这实际上取决于他们来自哪里Set of data 1
,Set of data2
来自哪里以及他们之间的关系是什么,我不得不想象一个真实世界的场景,这将是一个好主意。
ASet of Data
这里实际上只是一组Records
with Fields
。它们Fields
本质上是相互关联的,这就是为什么它们出现在一个单一的Record
.
问题 1:这两组包含彼此不相关的数据:
Set of Data1
可能完全不同Set of Data2
,因此无法说它们可以组合。
想象两组:
设置1:
+-------+--------+
| color | animal |
+-------+--------+
| brown | dog |
| white | dog |
| black | dog |
| green | parrot |
| green | turtle |
| brown | turtle |
+-------+--------+
设置2:
+------------+--------+
| food | flavor |
+------------+--------+
| pepper | spicy |
| water | |
| grapefruit | bitter |
| lemon | sour |
| candy | sweet |
+------------+--------+
一个查询 WHERE 子句:
WHERE (f1, f2) IN (SELECT color, animal FROM set1)
AND (f3, f4) IN (SELECT food, flavor FROM set2)
在我们测试的地方没有写这个的好方法,因为和(f1, f2, f3, f4)
之间没有关系。color | animal
food | flavor
如果我们在 crazytown,我们可以交叉连接这两个集合,以获得它们的笛卡尔积,产生与原始查询相同的结果集:
WHERE (f1, f2, f3, f4) IN (SELECT color, animal, food, flavor FROM set1, set2)
但是现在我们有一个子查询,其中包含set1
xset2
条记录的中间结果集。这很愚蠢,原因有很多:
- 两个集合上的索引被忽略
- 如果
set1
或set2
多于几条记录,您最终会得到一个巨大的中间结果集。 - 这两个集合之间没有任何关系,所以将它们组合在一起只是为了让你的 SQL 字符更少。
- 将有大量不必要的系统资源(CPU、磁盘、I/O)用于构建和存储此中间结果集,从而导致繁琐的缓慢查询。
- 任何其他开发人员一看到它就会追捕你并杀死你。如果他们打电话给我,我会提供逃跑的车。
问题 2:这两个集合可能彼此有关系,但是将IN
条件更改为 1 会导致记录下降。
即使可以组合这两个集合,您最终可能仍会得到与原始查询不同的结果。想象:
设置1:
+-------+--------+
| color | animal |
+-------+--------+
| brown | dog |
| white | dog |
| black | dog |
| green | parrot |
| green | turtle |
| brown | turtle |
+-------+--------+
第 2 组:
+--------+-------------+
| animal | stink_scale |
+--------+-------------+
| turtle | 2 |
| parrot | 4 |
| dog | 5 |
| skunk | 10 |
+--------+-------------+
表格1:
+-------+--------+---------+-------------+
| color | animal | animal2 | stink_scale |
+-------+--------+---------+-------------+
| white | dog | dog | 5 |
| brown | dog | parrot | 4 |
| green | turtle | turtle | 2 |
+-------+--------+---------+-------------+
您要更改的查询:
SELECT * FROM table1
WHERE (color, animal) IN (SELECT color, animal FROM Set1)
AND (animal2, stink_scale) IN (SELECT animal, stink_scale FROM set2);
这将产生 3 条记录 as white | dog
is inset1
和dog | 5
is in set
as it brown | dog
inset1
和parrot | 4
is inset2
并且对于 in 中的第三条记录相同table1
。
但是,如果我们将这两组组合在它们的animal
键上:
SELECT set1.color, set1.animal, set2.animal as animal2, set2.stink_scale FROM set1 JOIN set2 ON set1.animal = set2.animal;
我们将得到集合:
+-------+--------+---------+-------------+
| color | animal | animal2 | stink_scale |
+-------+--------+---------+-------------+
| brown | dog | dog | 5 |
| white | dog | dog | 5 |
| black | dog | dog | 5 |
| green | parrot | parrot | 4 |
| green | turtle | turtle | 2 |
| brown | turtle | turtle | 2 |
+-------+--------+---------+-------------+
我们用它来组合我们的IN
条件:
SELECT *
FROM table1
WHERE (color, animal, animal2, stink_scale) IN (SELECT set1.color, set1.animal, set2.animal as animal2, set2.stink_scale FROM set1 JOIN set2 ON set1.animal = set2.animal)
我们只得到 2 条记录,因为在该子查询中没有结果brown | dog | parrot | 4
将存在。
所以,最终除非有理由改变条件,从而改变结果集的定义,你最好不要管它。它确实改变了逻辑。
推荐阅读
- toast - Nativescript 应用程序 - nativescript-toast 插件 - 找不到模块:
- node.js - 在 CPanel 上部署 Node.js React 应用程序 - “加载资源失败:服务器响应状态为 404 ()”
- c# - 如何将列表视图中选定的文件路径传递给另一个表单?
- python - 带有日期时间类别的 openpyxl 活动挂图
- c - C中总和的最小和
- read-the-docs - 如何配置导航窗格以显示 PDF 和 epub 选项?
- hibernate - 休眠保存集合
- javascript - 使用 Javascript 写入表?我究竟做错了什么?
- javascript - 是否可以通过 for 循环引用多个 html5 画布和变量名?
- recursion - 理解使用递归的列表理解