假设我有一张客户表:
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
for any 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
与2 相同(即使另一行具有相同的and )。customer_address
customer_number
customer_number
customer_name
customer_address
最后两行不行,因为 3 有两个不同customer_address
的 es customer_number
。
如果针对所有六行运行,我正在寻找的查询将失败。但是,如果实际仅存在前四行,则视图应返回:
customer_number | customer_name | customer_address
----------------------------------------------------
1 | 'Bob' | '123 Street'
2 | 'Bob' | '123 Street'
我希望这能澄清我所说的“冲突customer_name
和customer_address
”的意思。它们必须是唯一的customer_number
。
我感谢那些解释如何从外部系统正确导入数据的人。事实上,我已经在做大部分事情了。我故意隐藏了我正在做的所有细节,以便更容易专注于手头的问题。此查询并不是唯一的验证形式。我只是认为这会是一个很好的画龙点睛(可以说是最后的防守)。这个问题只是为了调查 SQL 的可能性。:)