【问题标题】:Access query is duplicating unique records / Linked table issues访问查询重复唯一记录/链接表问题
【发布时间】:2014-11-27 15:51:27
【问题描述】:

我希望有人可以帮助我:

我有一个简单的查询,将名称列表和基本详细信息与另一个包含更具体信息的表相结合。有些名字必然会出现不止一次,像“John Smith 1”和“John Smith 2”这样的任意区别不是一种选择,所以我一直在使用自动编号来保持记录的不同。

问题是我的查询为每个出现多次的名称创建了两条记录。例如,有两个名为“Sophoan”的客户端,每个客户端都有不同的 id 号,并且查询已将每个客户端提取两次,从而产生 4 条记录(总共有 122 条记录,而应该只有 102 条记录)。 “唯一值”设置为“是”。

我已尽我所能进行了研究,但完全陷入困境。我尝试修改 sql,但它总是返回错误,我想是因为查询中的字段太多。

我错过了什么?或者查询是错误的方法,我需要找到另一种方法来组合我的表?

项目详情:我正在为一家慈善机构建立一个数据库,该慈善机构有两个主要活动:社会工作和培训。该数据库将记录他们的客户信息以及他们与客户互动的结果(他们寻求帮助的问题、培训研讨会的结果等)。一些客户将在组织想要跟踪的活动之间交叉,因此所有注册的客户都进入一个列表,并且单独的表旋转该列表以收集客户参与的每个特定活动的数据。这个查询应该是我的解决方案结合这些表格供用户输入数据。

目前我有以下表格:

  • AllList(客户姓名和基本联系信息的主列表;“社会工作登记”和“参与者登记”通过 '姓名')
  • 社会工作登记册(社会工作客户名单及完整详情 每个案例)
  • 社会工作跟进表(当员工致电社会工作客户时使用 看看他们的问题进展如何;寄存器太多了 列来保存它;通过“客户名称”加入注册)
  • 参与者注册(培训客户名单和详细信息) 他们参加了哪些研讨会,如果他们参加了,为什么他们缺席 错过了一节课)
  • 个人车间桌 x14(每个车间包括一个测试和 这些表格记录了客户的回答和他们对每个问题的得分 个人测试;届时将有超过 20 个 数据库完成;所有人都加入了“参与者登记册” “参与者姓名”)

查询:

  • 参与者概览查询(将“注册”中的出勤数据与每个研讨会的评分数据链接起来,以呈现只读 概述;这个似乎完美无缺)
  • 社会工作查询(非功能性;旨在链接“客户 注册”到“AllList”进行数据输入,以便当新客户
    已注册它会在两个表中创建一条新记录,
    记录匹配在一起)
  • 参与者查询(尚未尝试;如上所述,旨在链接 '参与者注册'到'AllList'以进行数据输入)

但是我意识到查询不能用于数据输入,所以这种方法似乎是死路一条。我在使用子表单进行数据输入方面取得了一些成功,但我不确定这是否是最好的方法。

所以,我基本上希望实现的是一种同时将相同数据输入到两个表(对于新记录)并将结果记录匹配在一起(对于现有记录的新条目)的方法。但是,同一个名字必须可以作为唯一记录多次出现(例如三个名为 John Smith 的人)。

[注:还有更多的表存储辅助信息,但与问题无关,因为它们不相关,也不会链接到任何其他表。]

【问题讨论】:

  • 安德鲁,您需要为您的表和您尝试过的查询提供架构。如果您可以显示每个表中的一些数据以及您期望的结果,这也会有所帮助。
  • 我试图发布一些截图,但由于我只是注册问这个问题,所以我似乎还没有权限。与此同时,我将编辑我的帖子,以尽可能详细地包含架构。

标签: ms-access ms-access-2010 duplicate-data


【解决方案1】:

我意识到查询不能用于数据输入

实际上,非复杂查询通常是可编辑的,只要您要编辑其数据的表仍然是查询的“核心”。 Access 应用了许多因素来确定查询是否可编辑。
大多数情况下,很容易找出查询变为不可编辑的原因。
问自己一个问题:如果我编辑该数据,Access 将如何确保准确无误地更新该数据?

如果您的表已定义主键并且这些是您的查询的一部分,并且如果没有分组、计算字段(使用某些函数来更改或测试该字段的值的字段)或复杂连接,则查询应保持可编辑状态。
您可以在此处阅读更多相关信息:

所以,我基本上希望实现的是一种同时将相同数据输入到两个表(对于新记录)并将结果记录匹配在一起(对于现有记录的新条目)的方法。但是,同一个名字必须可以作为唯一记录多次出现(例如三个名为 John Smith 的人)。

这句话实际上证明了你的数据库存在设计问题。

数据库设计的一个基本原则是尽可能地消除冗余。原因之一实际上是为了避免在多个地方更新相同的数据。

另外说明:您使用客户端的名称作为自然键。坦率地说,这不是一个好主意。通常,您要确保构成表的主键的内容随着时间的推移可靠地唯一。
使用人名通常是错误的选择,因为:

  • 人们改名,例如在许多文化中,妇女在结婚后改姓。
    输入名称时也可能存在拼写错误,现在如果该数据在不同的表中都用作外键,则很难更正。
  • 随着数据库的增长,您最终可能会遇到一些具有相同名称的人、产生冲突或强制用户更改该名称以防止重复。

在表中强制记录唯一性的最佳方法是在创建新表时使用 Access 建议的默认 AutoNumber ID 字段。这称为代理键
它并不意味着要被编辑、更改甚至显示给用户。它的唯一目的是允许表的主键是唯一的并且不随时间变化,因此它可以可靠地用作从一个表到另一个表的引用记录的方式(如果表需要引用特定的记录,它将包含一个保存 ID 的字段。该字段称为 外键)。

您为表命名的名称不够精确:将每个表视为一个保存相关数据的实体
您有一个名为AllList 的表这一事实意味着它的用途并没有经过深思熟虑;这听起来像是一个包罗万象的实体,而不是一个精心制作的实体。
相反,如果这是您的客户列表,则只需将其命名为 Client。该表的每条记录都包含单个客户的信息(是否使用复数或单数取决于您,但请坚持您的选择,保持一致非常重要)。
不要使用客户名称作为键,而是创建一个 ID 字段、一个自动编号,并将其设置为主键。

我们也将保存客户案件的“社会工作登记册”重命名为ClientCase。从您对表的描述中,这种关系似乎很清楚,但表名本身并不清楚(顺便说一下,我知道 Access 允许在表名和字段名中使用空格,但如果您至少关心一个,那么使用它们是一个非常糟糕的主意一点关于你工作的未来)。

在其中,创建一个ClientID 数字字段(外键),它将在ClientCase 表中保存相关客户端的ID

您不会谈论客户与其案例之间的关系。这是您必须明确的另一个领域:一个客户可以拥有多少个案例?

  • 最多 1 个案例? (0 或 1 个案例)
  • 正好 1 例?
  • 至少一个案例? (1个或多个案例)
  • 任何数量的案例? (0个或更多案例)

了解这一点对于在查询中选择正确的 JOIN 类型很重要。这是构建数据库时设计假设的关键部分。

例如,在最一般的情况下,假设客户可以有 0 个或多个案例,您可以有一个显示客户名称和与其相关的案例数量的报告,如下所示:

SELECT Client.Name,
       Count(ClientCase.ID) AS CountOfCases
FROM Client
  LEFT JOIN ClientCase
     ON Client.ID = ClienCase.ClientID
GROUP BY Client.Name

您已经更多地描述了您的基本设计,但这还不够。向我们展示实际的表结构和您尝试过的查询的 SQL。从你给出的描述中,很难真正理解设计的实际细节,也很难告诉你失败的原因以及如何让它发挥作用。

【讨论】:

  • 感谢您的详细回复。我将开始将其付诸实践,看看我是如何进行的(“边做边学”是我整个项目的口头禅)。从外键开始。每个客户将有 0 - 1 个案例,稍后会添加其他案例详细信息在“跟进”表上。我想我可以进行设置,以便“案例”和“跟进”都可以链接到“客户”并且都可以以一种形式进行编辑?我不确定您需要查看什么对于表结构?查询 SQL 稍后我将使用新的链接方法重新创建查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-15
  • 1970-01-01
  • 1970-01-01
  • 2013-09-23
  • 2021-01-04
相关资源
最近更新 更多