Запрос исключения SQL


Можно ли в одном SQL-операторе сделать следующее:

Используйте подмножество телефонных номеров в приглашении, например 8001231000-8001239999. Затем запросите мою базу данных, в которой есть телефонные номера, и верните, какие телефонные номера в исходном подмножестве отсутствуют в моей базе данных? Моя БД-Oracle 10g.

В основном вместо того, чтобы возвращать, какие номера телефонов находятся между 8001231000-8001239999, я хочу знать, какие номера телефонов между 8001231000-8001239999 не находятся в моей базе данных.

6 2

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;

Вы ищете оператора "NOT IN" с подзапросом, соответствующим этим телефонным номерам.

Я не могу придумать способ сделать это с помощью одного выбора, но вы можете сделать это с помощью одной транзакции. В частности:

  • Создайте временную таблицу со значениями в вашем диапазоне (должно быть возможно с помощью одной таблицы 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)

Создайте псевдо-список всех возможных чисел и исключите из него существующие числа.