Предотвратить Oracle минус оператор от удаления дубликатов - PullRequest
7 голосов
/ 13 мая 2009

Учитывая эти две таблицы:

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')?

Ответы [ 7 ]

8 голосов
/ 13 мая 2009

Другой вариант:

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

Это будет МИНУС с каждым дубликатом, рассматриваемым как отдельная запись. Обратите внимание, что в приведенном ниже примере, если 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 голос
/ 25 мая 2009

Ответы «НЕ В» верны. Альтернативой, которая может быть проще для некоторых сценариев, является оператор «НЕ СУЩЕСТВУЕТ»:

SELECT TEST FROM TEST1
WHERE NOT EXISTS
(SELECT null FROM TEST2 WHERE TEST2.TEST = TEST1.TEST);

(Примечание: здесь значение "null" в предложении select не имеет смысла)

Я лично использую оба метода, но мне часто нравится NOT EXISTS, потому что он более гибкий - для него не требуется, например, сравнение при условии равенства.

Последние версии оптимизатора часто преобразуют NOT IN в NOT EXISTS или наоборот; однако, если вы используете более старую версию (например, 8i или даже 9i), вы можете увидеть выигрыш в производительности от переключения между этими двумя методами.

1 голос
/ 13 мая 2009
SELECT field1 FROM table1 WHERE field1 NOT IN (SELECT field2 FROM table2)

Будет работать до тех пор, пока field2 не может содержать NULL.

0 голосов
/ 19 апреля 2016
SELECT TEST FROM TEST1 WHERE TEST IN(
SELECT TEST FROM TEST1
MINUS
SELECT TEST FROM TEST2);
0 голосов
/ 14 мая 2009

Oracle поддерживает несколько столбцов в операторе IN, поэтому вы можете написать:

SELECT a, b, c
FROM table1
WHERE (a,b,c) not in (
    select a,b,c from table2
)
0 голосов
/ 13 мая 2009

Часть того, что минус делает, удаляет дубликаты. Попробуйте использовать NOT IN, чтобы избежать удаления дубликатов.

SELECT TEST FROM TEST1 WHERE TEST NOT IN(SELECT TEST FROM TEST2)
0 голосов
/ 13 мая 2009

модификатор ALL заставляет UNION возвращать все строки (например, UNION ALL), может быть, его можно применить к MINUS? Как в

select field1 from table1
minus all
select field2 from table2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...