我有一个查询从一个表中检索数据。但是,查询使用for (auto it = map.begin(); it != map.end; ) {
answer[it->first-1] = it->first * it->second; //take the derivative
it = map.erase(it);
}
子句,如下所示:
MINUS
由于这是从同一个表中选择,我试图重写它以摆脱SELECT field1, field2
FROM tab
WHERE field3 = 'a'
AND field4 = 'b'
MINUS
SELECT field1, field2
FROM tab
WHERE field5 = 'c'
AND field6 = 'd'
子句。我认为这样的事情应该有效:
MINUS
我的理由是,如果SELECT DISTINCT field1, field2
FROM tab
WHERE field3 = 'a'
AND field4 = 'b'
AND NOT (field5 = 'c'
AND field6 = 'd')
子句排除第二个查询中的记录,那么将MINUS
子句包装在WHERE
中应该删除相同的记录。 AND NOT
子句也摆脱了重复,这就是我在选择中添加MINUS
的原因。但问题是我的查询返回更多记录而不是原始记录。
我在这里缺少什么?
答案 0 :(得分:5)
考虑这两行:
1,2,a,b,x,y
1,2,u,v,c,d
MINUS操作不会返回对(1,2),但您的查询将会。 c,d值可能出现相同的1,2,但与a,b
的行不同根本区别在于MINUS在设定级别运行,而NOT条件一次只能在一行上运行(在其他列中具有“必需”值的同一行)。
现在:您可以使查询更有效(尽管您无法避免两次读取基表)。使用NOT IN条件:
select field1, field2 from tab where field3 = 'a' and field4 = 'b'
and (field1, field2) not in
(select field1, field2 from tab where field5 = 'c' and field6 = 'd');
注意(参见下面的spencer7593评论):在所有可能存在NULL的情况下,NOT IN不是一个好的解决方案。相反,应该使用NOT EXISTS条件。我不会详细说明,因为它似乎超出了所提问题的范围(这就是为什么“NOT”解决方案与“MINUS”解决方案不同)。
答案 1 :(得分:2)
在此解决方案中,该表仅被引用一次。
select field1,field2
from tab
where (field3,field4) in (('a','b'))
or (field5,field6) in (('c','d'))
group by field1,field2
having max(case when (field5,field6) in (('c','d')) then 1 else 0 end) = 0
;
OR
select field1,field2
from tab
group by field1,field2
having max(case when (field3,field4) in (('a','b')) then 1 else 0 end) = 1
and max(case when (field5,field6) in (('c','d')) then 1 else 0 end) = 0
;