Запрос исключения SQL
Можно ли в одном SQL-операторе сделать следующее:
Используйте подмножество телефонных номеров в приглашении, например 8001231000-8001239999
. Затем запросите мою базу данных, в которой есть телефонные номера, и верните, какие телефонные номера в исходном подмножестве отсутствуют в моей базе данных? Моя БД-Oracle 10g.
В основном вместо того, чтобы возвращать, какие номера телефонов находятся между 8001231000-8001239999
, я хочу знать, какие номера телефонов между 8001231000-8001239999
не находятся в моей базе данных.
6 ответов:
Предполагая, что телефонный номер является номером, вы можете сгенерировать список всех телефонных номеров в определенном диапазоне
SELECT level - 1 + 8001231000 FROM dual CONNECT BY level <= 8001239999-8001231000+1
Затем вы можете присоединить этот список всех телефонных номеров в диапазоне к вашей фактической таблице телефонных номеров. Что-то вроде
WITH all_numbers AS ( SELECT level - 1 + 8001231000 phone_number FROM dual CONNECT BY level <= 8001239999-8001231000+1 ) SELECT * FROM all_numbers a WHERE NOT EXISTS( SELECT 1 FROM phone_numbers p WHERE a.phone_number = p.phone_number)
Если ваши телефонные номера являются символьными:
select * from mytable where phone_number not between '8001231000' and '8001239999'
Или если они числовые:
select * from mytable where phone_number not between 8001231000 and 8001239999
Я бы загрузил временную таблицу со всеми 10000 телефонными номерами в диапазоне, который вы хотите проверить, и сделал исключение join:
SELECT a.phone_number FROM phone_numbers_i_want_to_check AS a LEFT OUTER JOIN phone_numbers AS b ON a.phone_number = b.phone_number WHERE b.phone_number IS NULL;
Я не могу придумать способ сделать это с помощью одного выбора, но вы можете сделать это с помощью одной транзакции. В частности:
- Создайте временную таблицу со значениями в вашем диапазоне (должно быть возможно с помощью одной таблицы create и одной вставки)
- Удалите значения из вашей временной таблицы, которые существуют в вашей основной таблице
- Выберите значения из временной таблицы, которые остались
править: ответ Билла Карвина лучше. Та же концепция с временной таблицей, но затем один выбор, чтобы вытащить значения, которые не существуют.
Что-то вроде этого:
SELECT numbers_array.num FROM (SELECT 8001231000 + LEVEL num FROM dual CONNECT BY LEVEL <= (8001239999 - 8001231000) ) numbers_array WHERE numbers_array.num NOT IN (SELECT number_you_have FROM your_table_of_numbers)
Создайте псевдо-список всех возможных чисел и исключите из него существующие числа.