首页 > 解决方案 > 在 MS 访问中制作唯一记录

问题描述

我在按 A 到 Z 排序的访问表中有 170 万条记录。这些记录不是唯一的,并且有重复的记录。我想根据它们的频率使它们独一无二。如果一条记录重复了 4 次,我希望第一个记录在记录值的末尾得到“-1”,第二个记录得到“-2”,依此类推。这样,类似的记录就会变得独一无二。由于排序,所有相似的记录都在彼此旁边。在excel中我通过一个If函数来完成这个任务(如果这个单元格值<>上面的单元格值然后是“1”,否则上面重复数字加1)但是在访问中我不知道该怎么做(我是初学者) . 最后我想在原始表中添加一列(原始记录值 - 重复编号)。

我感谢您的帮助

标签: ms-access

解决方案


关于排序顺序的注意事项:

关系数据库中的排序顺序不像电子表格中那样具体。除非在索引的上下文中,否则没有行“彼此相邻”的概念。索引在很大程度上是数据库更有效地处理数据(并有助于定义唯一性)的工具。顺序本身在很大程度上仍然是动态的,因为特定查询的顺序可以与索引(或存储顺序)不同,这不会改变数据的实际存储方式。“彼此相邻”在 SQL 查询中本质上是一个无用的概念,除非您的意思是“在数字上彼此相邻””,例如使用自动编号字段或要添加的“重复编号”。与电子表格不同,您不能引用“就在这一行上方”的行或“从‘当前’行偏移 2 的行”。

解决方案

  1. 不管您以后是否会使用自动编号列,无论如何都要添加一个长整数自动编号列。此列[ID]在示例代码中命名。为什么?因为在您添加一些内容以允许数据库区分行之前,技术上无法使用标准 SQL 可靠地引用单个重复项,因为无法区分各个行。即使您说还有其他可区分的列,您自己的描述也排除了将它们用作引用特定行的可靠键。(即使没有这样一个区分列,Access 也可以在技术上区分行。在 VBA 中通过 DAO.Recordset 对象进行迭代会起作用,但可能不是很优雅/高效。)

  2. 添加了一个新的整数列来计算重复次数,下面将其命名为[DupeIndex]. 一个单独的字段是首选的(必要的?),因为它允许继续引用原始的、未更改的重复值。如果直接更新参考编号,它将不再与其他字段匹配,因此不再容易被检测为重复。以下解决方案依赖于所有重复值的分组,即使是那些已经用数字“标记”的[DupeIndex]值。

    • 您还应该意识到,在比较不同的数据集时,拥有单独的字段可以更灵活地匹配数据。将值附加到参考编号会使比较复杂化,因为您可能不仅想比较具有相同重复索引的行,而且还想比较所有可能的组合。例如,将一组中的记录123-1与另一组中的记录进行比较123-4……您如何以自动方式选择此类行?您不想手动编码所有组合,但如果您不将它们分开,例如 { 1231} 和 { 1234},那么您最终会这样做。
  3. 创建并将其保存为命名查询[Duplicates]。此查询被后面的查询引用。它可以作为子查询嵌入,但我的偏好是使用保存的查询以便在 Access 中更轻松地进行可视化和调试:


SELECT Data.RefNo, Count(Data.ID) AS Dupes, Max(Data.DupeIndex) AS IndexMax
FROM Data
GROUP BY Data.RefNo
HAVING Count(Data.ID) > 1
  1. 执行以下操作以创建具有新的重复索引值的临时表:

SELECT D1.ID, D1.RefNo,
    IIf([Duplicates].[IndexMax] Is Null,0,[Duplicates].[IndexMax])
    + 1 
    + (SELECT Count(D2.ID) FROM Data As D2
       WHERE D2.[RefNo]=[D1].[RefNo] 
         And [D2].[DupeIndex] Is Null 
         And [D2].[ID]<[D1].[ID]) AS NewIndex
INTO TempIndices
FROM Data AS D1 INNER JOIN Duplicates ON D1.RefNo = Duplicates.RefNo
WHERE (D1.DupeIndex Is Null);
  1. 执行更新查询以设置新的重复索引值:

UPDATE Data 
INNER JOIN TempIndices ON Data.ID = TempIndices.ID
SET Data.DupeIndex = [NewIndex]
  1. (可选)删除自动编号字段,现在将组合的 [RefNo] 和新的 [DupeIndex] 分配为主键。临时表也可以删除。

关于查询的评论:

  • 解决方案假设[DupeIndex]未处理的重复项为 Null。
  • 解决方案正确处理现有的重复索引号,仅更新没有唯一索引的重复行。
  • Access 对 UPDATE 查询有相当严格的条件,即更新不是基于循环引用和/或连接不会为同一行产生多个更新等。在这种情况下临时表是必要的,因为查询确定新的索引值在子查询中多次引用正在更新的列。(例如,如果尝试使用子查询上的连接进行更新,Access 会抱怨Operation must use an updatable query.)

推荐阅读