【问题标题】:UPDATE query that fixes orphaned records修复孤立记录的 UPDATE 查询
【发布时间】:2010-05-14 16:42:15
【问题描述】:

我有一个 Access 数据库,其中包含两个通过 PK/FK 关联的表。不幸的是,数据库表允许重复/冗余记录,并使数据库有点混乱。我正在尝试找出可以解决问题的 SQL 语句。

为了更好地解释问题和目标,我创建了示例表作为参考: alt text http://img38.imageshack.us/img38/9243/514201074110am.png 您会注意到有两个表,一个 Student 表和一个 TestScore 表,其中 StudentID 是 PK/FK。

Student 表包含学生 John、Sally、Tommy 和 Suzy 的重复记录。换句话说,StudentID 为 1 和 5 的 John 是同一个人,Sally 2 和 6 是同一个人,依此类推。

TestScore 表将考试成绩与学生联系起来。

忽略 Student 表允许重复的方式/原因等 - 我试图完成的目标是更新 TestScore 表,以便它用相应的启用 StudentID 替换已禁用的 StudentID。因此,所有 StudentID's = 1 (John) 将更新为 5;所有 StudentID's = 2 (Sally) 将更新为 6,依此类推。这是我正在拍摄的结果 TestScore 表(请注意,不再引用禁用的 StudentID 的 1-4): alt text http://img163.imageshack.us/img163/1954/514201091121am.png 你能想到一个查询(与 MS Access 的 JET 引擎兼容)可以实现这个目标吗?或者,也许,您可以提供一些提示/观点,为我指明正确的方向。

谢谢。

【问题讨论】:

  • 您的意思是发布表结构吗?你是如何识别重复的,是手动过程还是有另一个只包含重复的表,或者你只是使用同名的学生并希望不只有两个人实际上共享一个名字?
  • 是的,我在图片参考中发布了这些结构。显然,您看不到图像 - 以下是指向我的示例表结构图像的直接链接:img38.imageshack.us/img38/9243/514201074110am.pngimg163.imageshack.us/img163/1954/514201091121am.png 在我的示例中,我只是通过名称字段来识别骗子。但在我的实际数据库中,它是通过产品序列号。

标签: sql ms-access duplicates sql-update orphan


【解决方案1】:

做到这一点的唯一方法是通过一系列查询和临时表。

首先,我将创建以下 Make Table 查询,您将使用它来创建错误 StudentID 到更正 StudentID 的映射。

Select S1.StudentId As NewStudentId, S2.StudentId As OldStudentId 
Into zzStudentMap
From Student As S1
    Inner Join Student As S2
        On S2.Name = S1.Name
Where S1.Disabled = False
    And S2.StudentId <> S1.StudentId
    And S2.Disabled = True

接下来,您将使用该临时表以正确的 StudentID 更新 TestScore 表。

Update TestScore
    Inner Join zzStudentMap
        On zzStudentMap.OldStudentId = TestScore.StudentId
Set StudentId = zzStudentMap.NewStudentId

【讨论】:

  • 我没想过要使用临时表。谢谢,托马斯。
【解决方案2】:

识别表中重复项的最常用技术是按表示重复记录的字段进行分组:

ID  FIRST_NAME  LAST_NAME
1   Brian   Smith
3   George  Smith
25  Brian   Smith

在这种情况下,我们要删除 Brian Smith 记录之一,或者在您的情况下,更新 ID 字段,使它们都具有 25 或 1 的值(完全任意使用哪一个)。

SELECT  min(id)
    FROM example
GROUP BY first_name, last_name

对 ID 使用 min 将返回:

ID  FIRST_NAME  LAST_NAME
1   Brian   Smith
3   George  Smith

如果你使用 max 你会得到

ID  FIRST_NAME  LAST_NAME
25  Brian   Smith
3   George  Smith

我通常使用这种技术来删除重复项,而不是更新它们:

DELETE FROM example
      WHERE ID NOT IN (SELECT   MAX (ID)
                           FROM example
                       GROUP BY first_name, last_name)

【讨论】:

  • 谢谢,布赖恩。这是删除重复项的一种很酷的方法。但是,虽然我可以从示例 Student 表中删除重复项,但我必须保存(更新)TestScore 表中的现有记录。回顾一下示例 TestScore 表,您会注意到有 John(ID=1) 和 John(ID=5) 的记录。问题是,John ID1 和 ID5 是同一个人。因此,我想将所有 ID=1 更新为 ID=5。我不想忘记所有约翰(和其他学生)考试成绩的历史记录。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-04
  • 2012-09-19
相关资源
最近更新 更多