当前位置: 首页 > 面试题库 >

通过SQL查询安全规范化数据

姜飞飙
2023-03-14
问题内容

假设我有一个客户表:

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_namecustomer_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_addresscustomer_number1。

中间两排是很好,因为它是相同的customer_name,并customer_addresscustomer_number2(即使另一个customer_number具有相同的customer_namecustomer_address)。

最后两行 不正确, 因为3有两个不同的customer_addresses customer_number

如果针对所有这六行运行,我正在寻找的查询将失败。但是,如果仅实际存在前四行,则该视图应返回:

 customer_number | customer_name | customer_address
----------------------------------------------------
 1               | 'Bob'         | '123 Street'
 2               | 'Bob'         | '123 Street'

我希望这可以澄清“冲突customer_namecustomer_address”的含义。它们必须是唯一的customer_number

我感谢那些正在解释如何正确地从外部系统导入数据的人。 实际上,我已经在做大多数事情了。我 特意
隐藏了我正在做的所有细节,以便更轻松地专注于手头的问题。此查询并非唯一的验证形式。我只是认为这会给人留下很好的画龙点睛(可以说是最后一道防线)。这个问题只是为了调查SQL可能发生的情况而设计。:)


问题答案:

标量子查询只能返回一行(每个结果集行…),因此您可以执行以下操作:

select distinct
       customer_number,
       (
       select distinct
              customer_address
         from customers c2
        where c2.customer_number = c.customer_number
       ) as customer_address
  from customers c


 类似资料:
  • 问题内容: 好的,我刚开始使用Firebase。我已阅读:https://www.firebase.com/docs/data- structure.html, 并且已阅读:https://www.firebase.com/blog/2013-04-12-denormalizing- is- normal.html 所以我很困惑,因为一个似乎与另一个矛盾。您可以按层次结构组织数据,但是如果您想使其

  • 问题内容: 我想知道是否有人对如何规范化数据库有任何建议。现在,我不是要设计结构,而是要实际将数据库数据从旧结构移动到新的规范化结构。我知道我可以编写类似PHP脚本的内容,但是我想知道是否有一种方法可以在SQL中进行。特别是MySQL。 **编辑:有人尝试过SwisSQL吗?这是一个迁移工具,但我不确定它是否能满足我的要求。 问题答案: 这是在脚本中标准化表的示例。我建议你做这样的事情 您将首先创

  • 有一个使用属性表达式的查询:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.query-方法。查询属性表达式: 试图通过规范执行查询: 我得到了一个错误: 我做错了什么或忘记添加了什么? 查询:按教师姓名显示所有学生 基地实体: 实体教师: 实体学生: 实体教室: 实体教室:

  • 问题内容: 我是Python的初学者。我想做的是通过Pandas加载外汇历史价格数据的json文件,并对数据进行统计。我已经遍历了有关Pandas和解析json文件的许多主题。我想将具有额外值和嵌套列表的json文件传递给pandas数据框。我在这里遇到了问题。 我有一个json文件’EUR_JPY_H8.json’ 首先,我导入所需的库, 然后加载json文件, 我得到以下列表: 然后我将列表传

  • 我有一个用spring boot Version1.5.x编写的项目,它连接到一个MariaDB数据库和几个表,它们之间有大量的关系。为了查询数据库,我使用org.springframework.data.jpa.repository中提供的JpaSpecificationExecutor接口。我们使用规范的原因是为了构建动态查询,而不必为存储库本身中的每个筛选可能性编写新的查询。在实体本身中,每

  • 问题内容: 我有一个存储在列表中的关键字列表。 要从表中获取记录,请使用以下查询: 您可能已经注意到,我的查询容易受到sql注入的攻击,因此我想通过SqlCommand()使用参数。我已经尝试了以下方法,但仍然无法正常工作: 我在哪里犯错,或者应该怎么做? 问题答案: 您在这里做错了几件事: 您为所有参数赋予相同的名称。那行不通。参数需要唯一的名称。 您为每个项目创建一个新的SqlCommand。