sql - SQL EXCEPT 跨多个列
问题描述
我正在尝试比较两个几乎相同的选择查询;两个查询都从同一个表中输出相同的列。只有单个属性(where foo = 'BAR'
vs. where foo <> 'BAR'
)的条件不同。结果是巨大的,可能只有一些细微的差异。我目前的方法是执行这两个查询,然后将结果放入 Excel 并使用公式来比较两者。乏味和贫穷 - 必须有更好的方法。
如何构建一个单独执行每个选择的查询,然后只显示那些两边都不存在的行?
这是我的查询的简化版本:
-- first query
select a.foo, a.bar, a.moo from abc.mytable a where a.somedetail = 'BAR'
group by a.foo, a.bar, a.moo
order by a.foo, a.bar, a.moo;
-- second query
select a.foo, a.bar, a.moo from abc.mytable a where a.somedetail <> 'BAR'
group by a.foo, a.bar, a.moo
order by a.foo, a.bar, a.moo;
查看这个答案,看起来我需要 EXCEPT 运算符(但在两个方向上,这可能吗?),或者 UNION 或 FULL OUTER JOIN 但对于那些我真的不知道如何设置 WHERE 子句的人匹配两组中的所有列,是的,列中存在差异somedetail
。
每个数据库只需要执行一次,但性能是一个非常重要的考虑因素,因为数据涵盖数百万行。
解决方案
你不需要group by
,所以你可以这样写:
select a.foo, a.bar, a.moo
from abc.mytable a
where a.somedetail = 'BAR'
except
select a.foo, a.bar, a.moo
from abc.mytable a
where a.somedetail <> 'BAR';
鉴于您正在扫描所有数据,您可能会发现group by
效果更好:
select a.foo, a.bar, a.moo
from abc.mytable a
group by a.foo, a.bar, a.moo
having sum(case when a.somedetail = 'BAR' then 1 else 0 end) > 0 and
sum(case when a.somedetail <> 'BAR' then 1 else 0 end) > 0;
如果你有一个索引(foo, bar, moo)
,Oracle 应该很聪明地在这个查询中使用它。
推荐阅读
- javascript - 有没有办法在setData之后重置ckeditor中的撤消?
- continuous-integration - Travis CI 在 github 文件中看不到我的更改
- c++ - 如何添加此代码以使用我的 arduino 打印完整的三角形?
- flutter - 如何从飞镖中的未来返回错误?
- html - LinkedIn 共享按钮从 URL 中删除 QueryString
- ios - 如何使用 swift 4.2 在 UITextView 中禁用复制、全选?
- c++ - 为什么 std::is_copy_constructible 的行为不符合预期?
- angular - 使用服务文件时,我没有得到实际的角度响应
- android - 在 AsyncTask 中将对象作为参数传递
- java - 如何检查int变量是否不等于jstl中的String?