Предположим, у меня есть таблица клиентов:
CREATE TABLE customers (
customer_number INTEGER,
customer_name VARCHAR(...),
customer_address VARCHAR(...)
)
Эта таблица не имеет первичный ключ. Однако customer_name
и customer_address
должны быть уникальными для любого заданного customer_number
.
В этой таблице нередко встречается много повторяющихся клиентов. Чтобы обойти это дублирование, следующий запрос используется для изоляции только уникальных клиентов:
SELECT
DISTINCT customer_number, customer_name, customer_address
FROM customers
К счастью, таблица традиционно содержит точные данные. То есть никогда не было конфликтующих customer_name
или customer_address
для любого customer_number
. Однако предположим, что противоречивые данные попали в таблицу. Я хочу написать запрос, который не будет выполнен, вместо того, чтобы возвращать несколько строк для рассматриваемого customer_number
.
Например, я пробовал этот запрос безуспешно:
SELECT
customer_number, DISTINCT(customer_name, customer_address)
FROM customers
GROUP BY customer_number
Есть ли способ написать такой запрос, используя стандартный SQL? Если нет, то есть ли решение в специфичном для Oracle SQL?
РЕДАКТИРОВАТЬ: обоснование причудливый запрос:
По правде говоря, эта таблица клиентов на самом деле не существует (слава богу). Я создал его в надежде, что это будет достаточно ясно, чтобы продемонстрировать потребности запроса. Тем не менее, люди (к счастью) понимают, что потребность в таком запросе - наименьшее из моих опасений, основываясь на этом примере. Поэтому я должен теперь очистить часть абстракции и, надеюсь, восстановить свою репутацию, предложив такую мерзость стола ...
Я получаю плоский файл, содержащий счета (по одному на строку) из внешней системы. Я читаю этот файл построчно, вставляя его поля в эту таблицу:
CREATE TABLE unprocessed_invoices (
invoice_number INTEGER,
invoice_date DATE,
...
// other invoice columns
...
customer_number INTEGER,
customer_name VARCHAR(...),
customer_address VARCHAR(...)
)
Как видите, данные, поступающие из внешней системы, денормализованы. То есть внешняя система включает в себя и данные счета-фактуры, и связанные с ними данные клиента в одной строке. Возможно, что несколько счетов будут использовать одного и того же клиента, поэтому возможно иметь дубликаты данных клиента.
Система не может начать обработку счетов, пока все клиенты не будут гарантированно зарегистрированы в системе. Поэтому система должна идентифицировать уникальных клиентов и регистрировать их по мере необходимости. Вот почему я хотел запрос: , потому что я работал с денормализованными данными, я не мог контролировать .
SELECT
customer_number, DISTINCT(customer_name, customer_address)
FROM unprocessed_invoices
GROUP BY customer_number
Надеюсь, это поможет прояснить изначальную цель вопроса.
РЕДАКТИРОВАТЬ: Примеры хороших / плохих данных
Чтобы уточнить: customer_name
и customer_address
должны быть уникальными только для определенного customer_number
.
customer_number | customer_name | customer_address
----------------------------------------------------
1 | 'Bob' | '123 Street'
1 | 'Bob' | '123 Street'
2 | 'Bob' | '123 Street'
2 | 'Bob' | '123 Street'
3 | 'Fred' | '456 Avenue'
3 | 'Fred' | '789 Crescent'
Первые две строки хороши, потому что это одинаковые customer_name
и customer_address
для customer_number
1.
Средние две строки в порядке, потому что они одинаковы customer_name
и customer_address
для customer_number
2 (даже если у другого customer_number
есть такие же customer_name
и customer_address
).
Последние две строки не в порядке , потому что есть два разных customer_address
es для customer_number
3.
Запрос, который я ищу, не будет выполнен, если он будет выполнен для всех шести из этих строк. Однако, если в действительности существуют только первые четыре строки, представление должно вернуть:
customer_number | customer_name | customer_address
----------------------------------------------------
1 | 'Bob' | '123 Street'
2 | 'Bob' | '123 Street'
Надеюсь, это проясняет, что я имел в виду под "конфликтующими customer_name
и customer_address
". Они должны быть уникальными для customer_number
.
Я ценю тех, кто объясняет, как правильно импортировать данные из внешних систем. На самом деле, я уже делаю большую часть этого уже. Я нарочно скрыл все детали того, что я делаю, чтобы было легче сосредоточиться на данном вопросе. Этот запрос не является единственной формой проверки. Я просто думал, что это будет хорошим завершающим штрихом (последняя защита, так сказать). Этот вопрос был просто разработан, чтобы исследовать только то, что было возможно с SQL. :)