【问题标题】:Query of three related tables, showing only the latest records for each person, with SQL in MS Access查询三个相关表,只显示每个人的最新记录,用MS Access中的SQL
【发布时间】:2012-03-07 05:38:01
【问题描述】:

我有三张桌子:

注册人

  • 注册人 ID(主键)

通信

  • 通信 ID

  • 通讯时间

  • 通讯日期

  • 注册人 ID(外键)

  • 课程 ID(外键)

课程

  • 课程 ID(主键)

我们的想法是,我们可以记录谁注册了哪门课程、课程是否已满等,同时跟踪沿途的所有变化,并为每个电话、电子邮件、传真保留详细记录等(这里显示的字段比我这里显示的要多)。

我想要的是在每一行的最新通信记录(由通信时间和日期确定)中具有一个唯一注册人 ID 和课程 ID 的查询。所以基本上我可以查看查询并读出如下内容:

  • “A 人最后说他想在这个时间和日期参加课程 C”

  • “D 人最后说她想在这个时间和日期参加课程 A”

使用 SQL 或 MS Access 'Design View' UI 的解决方案都可以。

【问题讨论】:

  • 人名和课程名存储在哪里?
  • @Vikram 此人的所有详细信息(姓名、地址、电话号码等)都在注册人中。所有课程的详细信息(时间、日期、地点、演讲者等)都在课程中。

标签: sql ms-access relationship


【解决方案1】:

这变得更加困难,因为日期和时间在不同的字段中。

如果您在 Access 中使用顺序 Autonum ID,则可以使用 CorrespondenceID 来指示最新的。

试试这样的:

SELECT 
  Reg.Name,
  Course.Name,
  C.CorrespondenceDate,
  C.CorrespondenceTime
FROM
  (SELECT MAX(CorrespondenceID) AS ID, RegistrantID, CourseID
     FROM Correspondence
      GROUP BY RegistrantID, CourseID) AS CX
  INNER JOIN Correspondences AS C ON CX.CorrespondenceID = CX.ID
  INNER JOIN Registrants Reg on CX.RegistrantID = Reg.RegistrantID
  INNER JOIN Course ON CX.CourseID = Course.CourseID;

如果您不使用顺序自动编号,则必须结合日期和时间字段来确定哪个是最新的。您可以在上面的 CX 子查询中替换 MAX(CorrespondenceDate + CorrespondenceTime)

您可能会考虑的其他几件事:

  • 使用单个 DateTime 字段,使用 Now() 填充将更容易确定最新的。
  • 您在表名“course”(单数)和“registrants”(复数)上混合了复数 - 您可能应该保持一致 - 许多人更喜欢单数
  • 我会考虑有一个表注册,它在课程和注册者之间进行映射,然后有对应映射到注册。我觉得它的结构更好。

【讨论】:

  • 我尝试了上述 SQL 和 Access 锁定了一段时间,直到它说:“查询表达式'CX.[Correspondence ID] = CX.ID INNER JOIN Registrants AS Reg 中的语法错误(缺少运算符) ON CX.[Registrant ID] = Reg.[Registrant ID] INNER JOIN Courses ON CX.[Course ID] = Courses.[Course ID'。”
  • 我不能使用自动编号,因为有时需要回溯。我的理解是,如果我加入时间和日期,则在表单和表格中更难使用(这可能是 Access 的事情)。我在帖子中打错字了——表格应该是“课程”,因为所有表格都是复数形式(也许这是一个糟糕的系统,但至少是一致的)。仅仅为了保存一个值而创建一个额外的表是没有意义的。
【解决方案2】:

您需要在 MS Access 中使用一堆括号。

SELECT c1.[correspondence id],
       r.[registrant id],
       c2.[course id],
       [correspondence date] + [correspondence time] AS expr1
FROM   course c2
       INNER JOIN (registrants r
                   INNER JOIN correspondences c1
                     ON r.[registrant id] = c1.[registrant id])
         ON c2.[course id] = c1.[course id]
WHERE  [correspondence id] IN (SELECT [correspondence id]
                               FROM   correspondences b
                               WHERE  b.[registrant id] = c1.[registrant id]
                                      AND [correspondence date] +
                                          [correspondence time]
                                          =
                                          (SELECT MAX([correspondence date] +
                                                      [correspondence time])
                                           FROM   correspondences
                                           WHERE
                                              [registrant id] =
                                              c1.[registrant id]))

如果我不得不使用这些表,我会很快发疯。去掉所有的空格。

【讨论】:

    猜你喜欢
    • 2010-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 2021-04-17
    • 1970-01-01
    • 2020-07-29
    相关资源
    最近更新 更多