在MS访问中创建唯一记录

时间:2018-08-21 02:53:30

标签: ms-access

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

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

有关排序顺序的说明:

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

解决方案

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

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

    • 您还应该认识到,在比较不同的数据集时,具有单独的字段可以在匹配数据时提供更大的灵活性。将值附加到参考号上会使比较复杂,因为您不仅可能要比较具有相同重复索引的行,而且还要比较所有可能的组合。例如,将一组中的记录123-1与另一组中的123-4进行比较...如何以自动化方式选择此类行?您不需要手动编码所有组合,但这就是如果您不像{1231}和{{{1} },123}。
  3. 创建并保存为命名查询4。此查询由以后的查询引用。相反,它可以作为子查询嵌入,但是我的首选是使用保存的查询,以便在Access中更轻松地进行可视化和调试:


[Duplicates]
  1. 执行以下操作以创建具有新重复索引值的临时表:

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. (可选)删除“自动编号”字段,然后将组合的[RefNo]和新的[DupeIndex]分配为主键。临时表也可以删除。

有关查询的评论:

  • 解决方案假设UPDATE Data INNER JOIN TempIndices ON Data.ID = TempIndices.ID SET Data.DupeIndex = [NewIndex] 对于未处理的重复项为Null。
  • 解决方案正确处理现有的重复索引号,只更新没有唯一索引的重复行。
  • 访问具有用于UPDATE查询的相当严格的条件,即更新不基于循环引用和/或连接不会为同一行产生多个更新,依此类推。在这种情况下,临时表是必需的,因为确定新索引值的查询在子查询中多次引用正在更新的列。 (例如,如果尝试使用子查询上的联接进行更新,则Access会抱怨[DupeIndex]。)