如何查询 master-detail 结果只有 MS-Access 中的最后一个详细信息行?
How do I query a master-detail result having only the last detail row in MS-Access?
我有以下高手table
.------------------.
| id | parent_name |
.------------------.
| 1 | Mike |
| 2 | Sarah |
| 3 | Danial |
| 4 | Alex |
.------------------.
并具有以下 child-table 详细信息:
.------------------------------------------.
| 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 |
.------------------------------------------.
在上面的例子中,我故意选择 children 的名字,首字母与他们 parents 的名字匹配,只是为了更容易理解这种关系,即使每个 child 使用 parent_id
.
连接到 his/her parent
我想要的是所有 parent 的列表(4 行),并有来自 children table、[=40 的匹配的 4 行=]只有最后出生的 child 每个尊敬的 parent.
.-------------------------------.
| 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 不接受 sub-queries(对于 select,child 具有相同的最大出生年份parent).
是否有更好的方法在 MS Access 中获取结果?
Access 当然支持子查询,但您使用的是交叉联接,因此您永远不会得到空值。
相反,left join 并在 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
如果您只想要 child 的名称,您可以使用相关子查询:
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)
上的索引。有了索引,我希望这会很快。
我有以下高手table
.------------------.
| id | parent_name |
.------------------.
| 1 | Mike |
| 2 | Sarah |
| 3 | Danial |
| 4 | Alex |
.------------------.
并具有以下 child-table 详细信息:
.------------------------------------------.
| 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 |
.------------------------------------------.
在上面的例子中,我故意选择 children 的名字,首字母与他们 parents 的名字匹配,只是为了更容易理解这种关系,即使每个 child 使用 parent_id
.
我想要的是所有 parent 的列表(4 行),并有来自 children table、[=40 的匹配的 4 行=]只有最后出生的 child 每个尊敬的 parent.
.-------------------------------.
| 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 不接受 sub-queries(对于 select,child 具有相同的最大出生年份parent).
是否有更好的方法在 MS Access 中获取结果?
Access 当然支持子查询,但您使用的是交叉联接,因此您永远不会得到空值。
相反,left join 并在 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
如果您只想要 child 的名称,您可以使用相关子查询:
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)
上的索引。有了索引,我希望这会很快。