Операции над множествами

Дубликаты строк

По умолчанию UNION, INTERSECT и EXCEPT исключают дубликаты строк. Это работает так же, как и добавление DISTINCT после ключевого слова SELECT.

Посмотрим на несколько запросов.

SELECT value
  FROM table1
#value
11
21
33
43
53
65
SELECT value
  FROM table2
#value
12
23
33
44

Обрати внимание на намеренно задублированные строки. Теперь посмотрим на результаты операций над множествами:

SELECT value
  FROM table1
 UNION
SELECT value
  FROM table2
#value
11
22
33
44
55
SELECT value
  FROM table1
INTERSECT
SELECT value
  FROM table2
#value
13
SELECT value
  FROM table1
EXCEPT
SELECT value
  FROM table2
#value
11
25

Дубликаты строк отсутствуют независимо от того, были они в исходных таблицах, или получились в результате операции над множествами.

Чтобы СУБД не исключала из результата задублированные строки, нужно к ключевому слову операции над множествами добавить ALL. Перепишем наши запросы и посмотрим на результат:

SELECT value
  FROM table1
 UNION ALL
SELECT value
  FROM table2
#value
11
21
32
43
53
63
73
83
94
105

В результате присутствуют все строки table1 и table2.

SELECT value
  FROM table1
INTERSECT ALL
SELECT value
  FROM table2
#value
13
23

Пересечение выдает довольно интересный результат. В table1 значение 3 встречается три раза, а в table2 значение 3 встречается два раза. В результате выполнения запроса мы видим две строки со значением 3. INTERSECT ALL оставляет столько копий одинаковых строк, сколько их встретилось в обеих таблицах (наименьшее количество из двух таблиц). Например, если бы в первой таблице значение 9 встречалось 10 раз, а во второй 15 раз, то в результате INTERSECT ALL значение 9 встретилось 10 раз. Не веришь - проверь самостоятельно :)

SELECT value
  FROM table1
EXCEPT ALL
SELECT value
  FROM table2
#value
11
21
33
45

Откуда появилось значение 3 в результате? При EXCEPT такого не было. EXCEPT ALL исключает из результатов первого запроса столько одинаковых строк, сколько найдет в результате выполнения второго запроса. Разберем каждое значение из table1:

  • Значение 1 в table1 встречается 2 раза, в table2 ни разу. В результате видим 2 строки со значением 1.
  • Значение 3 в table1 встречается 3 раза, в table2 2 раза. Из трех строк были исключены две, в результате осталась одна.
  • Значение 5 в table1 встречается 1 раз, в table2 ни разу. В результате видим 1 строку со значением 5.
ПредыдущаяСледующая