鉴于这两个表:
CREATE TABLE TEST1 (TEST VARCHAR2(1 BYTE))
CREATE TABLE TEST2 (TEST VARCHAR2(1 BYTE))
其中TEST1有两行,值均为“A”,而TEST2的行为一行,值为“B”。
当我运行此命令时:
SELECT TEST FROM TEST1
MINUS
SELECT TEST FROM TEST2
我得到了输出:
Test
-----
A
似乎MINUS删除了重复项(因为TEST1中有两个'A'行)。
如何让MINUS查询包含重复值(返回两个'A'行)?
答案 0 :(得分:8)
另一种选择:
SELECT TEST, row_number() OVER (PARTITION BY TEST ORDER BY TEST) FROM TEST1
MINUS
SELECT TEST, row_number() OVER (PARTITION BY TEST ORDER BY TEST) FROM TEST2
这将是MINUS,每个副本都被视为一个独特的条目。请注意,在下面的示例中,如果TEST1有两个'C'值而TEST2只有一个,那么输出中就有一个。
dev> select * from test1;
T
-
A
A
B
C
C
dev> select * from test2;
T
-
B
C
dev> SELECT TEST, row_number() OVER (PARTITION BY TEST ORDER BY TEST) FROM TEST1
2 MINUS
3 SELECT TEST, row_number() OVER (PARTITION BY TEST ORDER BY TEST) FROM TEST2
4 /
T ROW_NUMBER()OVER(PARTITIONBYTESTORDERBYTEST)
- --------------------------------------------
A 1
A 2
C 2
答案 1 :(得分:1)
SELECT field1 FROM table1 WHERE field1 NOT IN (SELECT field2 FROM table2)
只要field2不能包含NULL,就会工作。
答案 2 :(得分:1)
“NOT IN”答案都是正确的。对于某些场景可能更容易的替代方案是“NOT EXISTS”运算符:
SELECT TEST FROM TEST1
WHERE NOT EXISTS
(SELECT null FROM TEST2 WHERE TEST2.TEST = TEST1.TEST);
(注意:select子句中的“null”在这里没有意义)
我个人使用这两种方法,但我喜欢NOT EXISTS,因为它更灵活 - 例如,它不要求比较处于相等条件。
最新版本的优化器通常会将NOT IN转换为NOT EXISTS,反之亦然;但是,如果您使用的是旧版本(例如8i甚至9i),您可能会看到通过这两种方法之间切换带来的性能优势。
答案 3 :(得分:0)
ALL修饰符使UNION返回所有行(例如,UNION ALL),也许它可以应用于MINUS?如在
select field1 from table1
minus all
select field2 from table2
答案 4 :(得分:0)
减号的一部分是删除重复项。考虑使用NOT IN来避免删除重复项。
SELECT TEST FROM TEST1 WHERE TEST NOT IN(SELECT TEST FROM TEST2)
答案 5 :(得分:0)
Oracle支持IN语句中的多个列,因此您可以编写:
SELECT a, b, c
FROM table1
WHERE (a,b,c) not in (
select a,b,c from table2
)
答案 6 :(得分:0)
CompletableFuture