【问题标题】:SQL/access question: Do not append that student-term record if the student AND the term already exist!SQL/访问问题:如果学生和学期已经存在,请不要附加该学生学期记录!
【发布时间】:2011-03-20 04:35:09
【问题描述】:

我有另一个 SQL/access 2007 问题,看起来很基础,但我不知道如何在 Google 上找到它。

我有这张 STUDENT-TERMS 表,其中包含以下字段:

StudentTermID

StudentID(指向 STUDENT 表的链接)

TermID(链接到 TERMS 表)

TermGPA(这是需要记录的信息块)

STUDENT 表如下所示:

学生证

名字

TERMS 表如下所示:

TermID

开始日期

结束日期

我有一个文档,其中包含上传到 Access 文档中的所有信息。我获得的这份文档与数据库中存在的学生 ID 和学期 ID 相同。

然后我可以运行附加查询将数据放入 STUDENT-TERMS 表中。这很好。

如何编写查询以使每个学生的每个学期只有一条记录? 例如,我现在在表中有这些数据:

学生学期 ID:5

学号:塔拉

TermID:1011Autumn

学期GPA:3.8

当我上传并附加一个新文档时,它可能仍包含有关 Tara 的信息,我希望数据库在附加时说“嘿,我们已经有了,跳过它”。我该如何表示?

这是结论/答案/解决方案: 谢谢大家的帮助。这就是我最终要做的事情:

  1. 我在表中创建了一个名为 StudentTerm 的新字段,其中包含 StudentID 和 Term 的串联(如:Tara1011Autumn)。此字段已编入索引,没有重复项。

  2. 执行追加的查询如下所示:

插入 StudentTerms(StudentID、TermID、GPA、StudentTerm) 选择 Upload_Students.StudentID、Upload_Students.TermID、Upload_Students.GPA、 [Upload_Students]![StudentID] & [Upload_Students]![TermID] AS Expr1 FROM Students INNER JOIN Upload_Students ON Students.StudentID = Upload_Students.StudentID;

此查询尝试使用 Tara1011Autumn 填充 StudentTerm 字段。如果该字符串已存在于表中,则不会追加记录。

【问题讨论】:

  • 请描述表学生和术语
  • 您的上传文件中是否包含 StudentID?
  • 为什么要连接字段而不是像您接受的答案中建议的那样创建复合索引?从我的角度来看,出于各种原因,你最终做的是一个非常糟糕的主意。
  • 我想我误解了答案。
  • 但是现在您必须为所有新记录填充该字段,并且如果组成值发生更改,则必须对其进行更新。两个字段上的复合索引是正确答案(您接受的那个)。如果您不明白这意味着什么,请询问,一切都会得到解释。

标签: sql ms-access


【解决方案1】:

在 [student-terms] 表上创建一个唯一索引,索引中包含 StudentID 和 StudentTermID 字段。

然后,当您运行附加查询时,Access 会在询问您是否要继续之前告诉您“# 个记录因密钥违规而无法添加”。如果您在该对话框中单击“是”,则将追加所有非违规记录,并将违规记录保存到不同的表中。

如果您从 VBA 执行此操作以自动执行此操作,则 DoCmd.RunQuery 操作中还有其他可用选项。

【讨论】:

  • 如果业务需求是一个 studentTerm 记录是唯一的,那么使用唯一索引来强制它。
【解决方案2】:

假设您正在执行基于 SQL 的追加查询,您可以使用 NOT EXISTS 子句。

注意
我在这里假设如果 StudentTermID 不同,您可以为同一个学生拥有多个 STUDENT-TERMS 记录。

INSERT INTO STUDENT-TERMS
          ( StudentTermId
          , StudentId
          , TermID
          , TermGPA )
     SELECT 5
          , 'Tara'
          , '1011Autumn'
          , 3.8
      WHERE NOT EXISTS
            (SELECT * FROM STUDENT-TERMS WHERE StudentID = 'Tara'
                                           AND StudentTermId = 5)

【讨论】:

    【解决方案3】:

    *假设数据库在3NF *

    SELECT st.StudentId, s.StudentName, t.TermId, t.TermName, st.TermGPA
    FROM STUDENTS_TERMS st
    INNER JOIN STUDENT s ON st.StudentID = s.StudentId
    INNER JOIN TERMS t on st.TERMS = t.TermId
    WHERE st.StudentID = 5
    

    【讨论】:

      【解决方案4】:

      基于 dcp 的回答,但针对 Access 进行了调整

      INSERT INTO STUDENT-TERMS
            ( StudentTermId
            , StudentId
            , TermID
            , TermGPA )
       SELECT DISTINCT 5
            , 'Tara'
            , '1011Autumn'
            , 3.8
        FROM STUDENT-TERMS
        WHERE NOT EXISTS
              (SELECT * FROM STUDENT-TERMS WHERE StudentID = 'Tara'
                                             AND StudentTermId = 5)
      

      【讨论】:

      • 如果 STUDENT-TERMS 为空,这不会插入零行吗?
      • 如果我不知道哪些记录可能重复,我只是想防止任何可能的重复,这会是什么样子?换句话说,你会如何写这个用变量替换特定的“Tara”和“5”?
      • @Justin K 是的。但是,在 Access 中需要一个 from 表,但在这种情况下它可以是任何表,甚至是 MsysObjects,一个系统表。
      • 如果要确定唯一值,通常最好使用唯一索引。
      • 你从哪里看到的变量?你想要参数吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-02
      • 1970-01-01
      • 1970-01-01
      • 2014-08-02
      • 2017-03-30
      相关资源
      最近更新 更多