顧客のテーブルがあるとします。
CREATE TABLE customers (
customer_number INTEGER,
customer_name VARCHAR(...),
customer_address VARCHAR(...)
)
このテーブルには主キーがありません。ただし、customer_name
andは任意の に対して一意であるcustomer_address
必要customer_number
があります。
このテーブルに多くの重複した顧客が含まれることは珍しくありません。この重複を回避するために、次のクエリを使用して一意の顧客のみを分離します。
SELECT
DISTINCT customer_number, customer_name, customer_address
FROM customers
幸いなことに、テーブルには従来から正確なデータが含まれていました。つまり、競合するcustomer_name
orがあったことは一度もありませcustomer_address
んcustomer_number
。ただし、競合するデータがテーブルに入ったとします。問題の複数の行を返すのではなく、失敗するクエリを作成したいと考えていますcustomer_number
。
たとえば、次のクエリを試してみましたが成功しませんでした。
SELECT
customer_number, DISTINCT(customer_name, customer_address)
FROM customers
GROUP BY customer_number
標準 SQL を使用してそのようなクエリを作成する方法はありますか? そうでない場合、Oracle 固有の SQL に解決策はありますか?
編集:奇妙なクエリの背後にある理論的根拠:
正直なところ、この customers テーブルは実際には存在しません (ありがたいことに)。クエリのニーズを示すのに十分明確になることを期待して作成しました。ただし、その例に基づいて、そのようなクエリの必要性が私の心配の中で最も少ないことに人々は (幸いなことに) 気づいています。したがって、私は抽象化の一部を剥がして、このようなテーブルの忌まわしさを示唆しているという私の評判を取り戻さなければなりません...
外部システムから請求書 (1 行に 1 通) を含むフラット ファイルを受け取りました。このファイルを行ごとに読み取り、そのフィールドをこのテーブルに挿入します。
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'
最初の 2 行は同じで 1 であるため問題ありcustomer_name
ませcustomer_address
んcustomer_number
。
中央の 2 つの行は、同じcustomer_name
and customer_address
for customer_number
2 であるため問題ありません (別の行customer_number
には同じcustomer_name
andがありますがcustomer_address
)。
3には 2 つの異なるesがあるため、最後の 2 行は問題ありません。customer_address
customer_number
私が探しているクエリは、これらの 6 つの行すべてに対して実行すると失敗します。ただし、最初の 4 行のみが実際に存在する場合、ビューは次を返す必要があります。
customer_number | customer_name | customer_address
----------------------------------------------------
1 | 'Bob' | '123 Street'
2 | 'Bob' | '123 Street'
customer_name
これで、「競合する」という言葉の意味が明確になることを願っていcustomer_address
ます。ごとに一意である必要がありますcustomer_number
。
外部システムからデータを適切にインポートする方法を説明している人に感謝します。実際、私はすでにそのほとんどをすでに行っています。目の前の質問に集中しやすくするために、私がやっていることのすべての詳細を意図的に隠しました。このクエリは、検証の唯一の形式ではありません。私はそれが素晴らしい仕上げになると思っただけです(いわば最後の防御)。この質問は、SQL で可能なことを調査するために作成されたものです。:)