【问题标题】:How do I query a master-detail result having only the last detail row in MS-Access?如何查询 MS-Access 中只有最后一个明细行的主明细结果?
【发布时间】:2021-06-02 07:39:45
【问题描述】:

我有以下主表

.------------------.
| id | parent_name | 
.------------------.
| 1  | Mike        |
| 2  | Sarah       |
| 3  | Danial      |
| 4  | Alex        |
.------------------.

并具有以下子表详细信息:

.------------------------------------------.
| id | parent_id | child_name | birth year |
.------------------------------------------.
| 1  |   1       | mandy      |  2000      |
| 2  |   1       | mark       |  2003      |
| 3  |   1       | mathew     |  2005      |
| 4  |   2       | sandy      |  1998      |
| 5  |   2       | sharon     |  2006      |
| 6  |   3       | david      |  2001      |
.------------------------------------------.

在上面的示例中,我故意选择第一个字母与父母姓名匹配的孩子的名字,以便更容易理解这种关系,即使每个孩子都使用parent_id 连接到他/她的父母。

我想要的是所有父母的列表(4 行),并从 children 表中匹配 4 行,只选择每个尊敬的父母的最后一个出生的孩子。

.-------------------------------.
| id | parent_name | last_child |
.-------------------------------.
| 1  | Mike        | mathew     |
| 2  | Sarah       | sharon     |
| 3  | Danial      | david      |
| 4  | Alex        | (null)     |
.-------------------------------.

在 oracle 中,这很容易:

SELECT
   p.id,
   p.parent_name,
   c.child_name last_child
FROM
   parents_table p,
   children_table c
WHERE
        p.id = c.parent_id
   AND  c.birth_year = (SELECT MAX(birth_year) FROM children_table where parent_id = p.id)

但我正在努力在 MS Access 中生成相同的结果。MS Access 不接受子查询(用于选择同一父母的最大出生年份的孩子)。

有没有更好的方法在 MS Access 中获取结果?

【问题讨论】:

    标签: sql ms-access master-detail


    【解决方案1】:

    Access 确实支持子查询,但您使用的是交叉连接,因此您永远不会在那里得到空值。

    相反,左连接并在FROM 子句中执行子查询。 顺便说一句,您的查询在 Oracle 中同样会失败。 Access 和 Oracle 之间没有相关差异。

    SELECT
       p.id,
       p.parent_name,
       c.child_name last_child
    FROM
       parents_table p
       LEFT JOIN
        (
            SELECT *
            FROM children_table c
            WHERE c.birth_year = (SELECT MAX(c2.birth_year) FROM children_table c2 WHERE c2.parent_id = c.parent_id)
        ) c
        ON p.id = c.parent_id
    

    Access 有时使用EXISTS 会表现得更好,所以重写它是:

    SELECT
       p.id,
       p.parent_name,
       c.child_name last_child
    FROM
       parents_table p
       LEFT JOIN
        (
            SELECT *
            FROM children_table c
            WHERE EXISTS(SELECT 1 FROM children_table c2 WHERE c2.parent_id = c.parent_id HAVING c.birth_year = MAX(c2.birth_year))
        ) c
        ON p.id = c.parent_id
    

    【讨论】:

      【解决方案2】:

      如果你只想要孩子的名字,你可以使用相关子查询:

      select p.*,
             (select top 1 child_name
              from children_table as ct
              where ct.parent_id = p.id
              order by ct.birth_year desc, ct.child_name
             ) as youngest_child_name
      from parents_table as p;
      

      这可以利用children_table(parent_id, birth_year desc, child_name) 上的索引。有了索引,我希望这会很快。

      【讨论】:

      • oldest_child_name ?也许你打算解决youngest_child,因为最后一个孩子是出生时年数最大的孩子。
      • @Ahmad 。 . .是的,该列的名称有误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-22
      • 2019-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多