在Access中追加记录时避免重复

时间:2017-03-09 20:29:42

标签: sql ms-access duplicates

我知道这已被多次询问,但出于某种原因,解决方案对我不起作用。

数据库布局:

我有Table1(Scanner_Location)谁从表格上的另一个表/子表格中提取数据(Scanner IBOB)*保留列:FP#,Count,Location,Model_ID,PK-SL_ID

表2(扫描仪详细信息)保留三个数据列中的两个:(FP#,Location PK-SN) 表3(Scanner_Model)保存显示在子表单中的最后一个数据列。 (PK-MODEL_ID)

用户将输入FP#,并在表单的一个部分中输入位置,然后导航到子表单,并选择多个模型,并输入计数(文本框)。选择后,他们会点击更新'执行我的查询的按钮。 (其中我有更新,和附加查询)

问题是,仅使用更新查询不会添加记录。并使用Append查询创建现有数据的副本。

以下是流程的执行方式:

用户选择模型1和模型2,计数为4,FP#为100.点击更新。 查询更新,信息输入正确。

用户再次选择相同的模型(Model_Select),使用相同的FP#和count,Table1再次输入相同的信息,使用不同的主键。

目标:

追加查询会创建现有数据的副本。我只想要更新和/或追加查询:

更新现有数据 - 查找具有相同FP#的任何内容 添加任何已经不存在的记录(查看Model_ID和FP#)

INSERT INTO Scanner_Location ( Model_ID, FootPrints_Num, Location_ID, Scanner_Loc_Cnt ) 
SELECT Scanner_Model.Model_ID, [Forms]![Scanner_IBOB]![fpNum_txt] AS [FP#],
    [Forms]![Scanner_IBOB]![Location_Cbo_main] AS Location, 
    [Forms]![Scanner_IBOB]![Scanner_Loc_CntTxt] AS [Count] 
    FROM Scanner_Detail 
    RIGHT JOIN Scanner_Model ON Scanner_Detail.Model_ID = Scanner_Model.Model_ID
    WHERE (((Scanner_Model.SM_Acc_Select)=True) 
        AND ((NOT Exists (SELECT * FROM Scanner_location 
    WHERE (((Forms!Scanner_IBOB!fpNum_txt)=Forms!Scanner_IBOB!fpNum_tx‌​t) 
        And ((Scanner_Model.SM_Acc_Select)=True)); ))=False));

3 个答案:

答案 0 :(得分:0)

也许使用NOT IN,例如:

[某些标识符字段] NOT IN(SELECT [some identifier field] FROM

审核EXISTS vs IN

答案 1 :(得分:0)

没有名为'Update_SLoc_Acc53'的查询 - 有'Update_SLoc_Acc3'和'Update_SLoc_Acc54'。我修改了'Update_SLoc_Acc54',因为它是代码调用的那个。

查询没有从组合框中提取Location_ID。我发现绑定列设置为1并且应该为0以引用Location_ID列,因为列索引以0开头。可以通过将width设置为0来隐藏此列。

此查询似乎有效:

INSERT INTO Scanner_Location ( Model_ID, FootPrints_Num, Location_ID, Scanner_Loc_Cnt )
SELECT Scanner_Model.Model_ID, [Forms]![Scanner_IBOB]![fpNum_txt] AS FPNum,
      [Forms]![Scanner_IBOB]![Location_Cbo_main] AS Location, 
      [Forms]![Scanner_IBOB]![Scanner_Loc_CntTxt] AS CountMod
FROM Scanner_Model
WHERE (((Scanner_Model.SM_Acc_Select)<>False) 
  AND  (([Model_ID] & [Forms]![Scanner_IBOB]![fpNum_txt] &
         [Forms]![Scanner_IBOB]![Location_Cbo_main]) 
        NOT IN (SELECT Model_ID & Footprints_Num & Location_ID FROM Scanner_Location)));

注意我没有在字段名称中使用#。建议不要在名称中使用标点符号/特殊字符,只有下划线除外。还使用CountMod而不是Count作为字段名称。

为什么需要选择两种型号?如果添加一个而另一个不添加怎么办?

我对db结构感到担忧。

  1. 不要认为App_Location和App_Detail都应该链接到其他表。为什么Location_ID是App_Location中的主键以及Location_Data中的主键?这是一对一的关系。
  2. Serial_Number是扫描仪的序列号吗?为什么它是Telnet的主键?这也导致一对一的关系,在这种情况下也可以将它们组合起来。
  3. 如果某个应用与扫描仪关联且扫描仪与某个位置相关联,则不需要与应用相关联的位置。扫描仪和telnet也是如此。
  4. Scanner_Location表未链接到任何内容。如果此表的目的是跟踪模型/脚印/位置的数量 - 正如已经建议的那样,这通常不是一个好主意。理想情况下,计数数据应在需要信息时通过原始数据记录的聚合查询来计算。

答案 2 :(得分:0)

请考虑使用调整后的附加查询来检查 Scanner_Location 中是否存在匹配的 Model_ID FP_Num 。如果匹配不存在,则查询将导入所选记录,因为它们将是新记录而不是重复记录。此外,表别名用于可读性和子查询关联。

INSERT INTO Scanner_Location ( Model_ID, FootPrints_Num, Location_ID, Scanner_Loc_Cnt ) 
SELECT m.Model_ID, [Forms]![Scanner_IBOB]![fpNum_txt] AS [FP#],
       [Forms]![Scanner_IBOB]![Location_Cbo_main] AS Location, 
       [Forms]![Scanner_IBOB]![Scanner_Loc_CntTxt] AS [Count] 
FROM Scanner_Detail d
RIGHT JOIN Scanner_Model m ON d.Model_ID = m.Model_ID
WHERE ((m.SM_Acc_Select = True) 
  AND  (NOT EXISTS (SELECT 1 FROM Scanner_Location loc
                    WHERE ((loc.FootPrints_Num = Forms!Scanner_IBOB!fpNum_tx‌​t) 
                      AND  (loc.Model_ID = m.Model_ID)) ) ));