假设我有一张客户表:
CREATE TABLE customers (
customer_number INTEGER,
customer_name VARCHAR(...),
customer_address VARCHAR(...)
)
这张表确实not有一个主键。然而,customer_name
and customer_address
should对于任何给定的都是唯一的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有解决方案吗?
编辑:奇怪的查询背后的基本原理:
说实话,这个客户表实际上并不存在(谢天谢地)。我创建它是希望它能够足够清晰地展示查询的需求。然而,基于该示例,人们(幸运的是)意识到对此类查询的需求是我最不用担心的。因此,我现在必须剥离一些抽象概念,并希望恢复我提出如此令人厌恶的桌子的声誉......
我从外部系统收到一个包含发票(每行一张)的平面文件。我逐行读取该文件,将其字段插入到该表中:
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
and 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
and customer_address
for customer_number
1.
中间两行很好,因为它是相同的customer_name
and customer_address
for customer_number
2(尽管另一个customer_number
有相同的customer_name
and customer_address
).
最后两行是not okay因为有两个不同的customer_address
es for customer_number
3.
如果针对所有六行运行,我正在查找的查询将会失败。但是,如果实际上只存在前四行,则视图应返回:
customer_number | customer_name | customer_address
----------------------------------------------------
1 | 'Bob' | '123 Street'
2 | 'Bob' | '123 Street'
我希望这能澄清我所说的“冲突”的含义customer_name
and customer_address
“。它们必须是独一无二的customer_number
.
我很欣赏那些解释如何正确从外部系统导入数据的人。事实上,我已经在做其中的大部分了。我故意隐藏了我正在做的所有细节,以便更容易专注于手头的问题。此查询并不是唯一的验证形式。我只是认为这会起到很好的画龙点睛作用(可以说是最后的防御)。这个问题只是为了调查 SQL 的可能性。 :)