【发布时间】:2018-03-09 10:21:20
【问题描述】:
我正在尝试编写一个 Oracle SQL 查询来连接两个通过链接表链接的表(我的意思是一个有 2 列的表,每列都是主表的外键)。 min() 函数用于将左外连接的结果限制为单行。
我的模型由“父母”和“侄子”组成。父母可以有 0 个或多个侄子。父母可以启用或禁用。每个侄子都有一个生日日期。我的查询目标是:
为每个启用的父母打印一行,列出该父母最年长的侄子(即最小(生日)的侄子)。
我的问题在 sqlfiddle 有说明:http://sqlfiddle.com/#!4/9a3be0d/1
我可以形成一个查询,列出启用的父母的 所有 侄子,但这还不够好 - 我只希望每个父母有一行,其中仅包括 最老的 em>侄子。形成外部表的 where 子句似乎是我的绊脚石。
我的表格和示例数据:
create table parent (parent_id number primary key, parent_name varchar2(50), enabled int);
create table nephew (nephew_id number primary key, birthday date, nephew_name varchar2(50));
create table parent_nephew_link (parent_id number not null, nephew_id number not null);
parent table:
+----+-------------+---------+
| id | parent_name | enabled |
+----+-------------+---------+
| 1 | Donald | 1 |
+----+-------------+---------+
| 2 | Minnie | 0 |
+----+-------------+---------+
| 3 | Mickey | 1 |
+----+-------------+---------+
nephew table:
+-----------+------------+-------------+
| nephew_id | birthday | nephew_name |
+-----------+------------+-------------+
| 100 | 01/01/2017 | Huey |
+-----------+------------+-------------+
| 101 | 01/01/2016 | Dewey |
+-----------+------------+-------------+
| 102 | 01/01/2015 | Louie |
+-----------+------------+-------------+
| 103 | 01/01/2014 | Morty |
+-----------+------------+-------------+
| 104 | 01/01/2013 | Ferdie |
+-----------+------------+-------------+
parent_nephew_link table:
+-----------+-----------+
| parent_id | nephew_id |
+-----------+-----------+
| 1 | 100 |
+-----------+-----------+
| 1 | 101 |
+-----------+-----------+
| 1 | 102 |
+-----------+-----------+
| 3 | 103 |
+-----------+-----------+
| 3 | 104 |
+-----------+-----------+
我的(不正确的)查询:
-- This query is not right, it returns a row for each nephew
select parent_name, nephew_name
from parent p
left outer join parent_nephew_link pnl
on p.parent_id = pnl.parent_id
left outer join nephew n
on n.nephew_id = pnl.nephew_id
where enabled = 1
-- I wish I could add this clause to restrict the result to the oldest
-- nephew but p.parent_id is not available in sub-selects.
-- You get an ORA-00904 error if you try this:
-- and n.birthday = (select min(birthday) from nephew nested where nested.parent_id = p.parent_id)
我想要的输出是:
+-------------+-------------+
| parent_name | nephew_name |
+-------------+-------------+
| Donald | Louie |
+-------------+-------------+
| Mickey | Ferdie |
+-------------+-------------+
感谢您的建议! 约翰
markaaronky 的建议
我尝试使用 markaaronky 的建议,但这个 sql 也有缺陷。
-- This query is not right either, it returns the correct data but only for one parent
select * from (
select parent_name, n.nephew_name, n.birthday
from parent p
left outer join parent_nephew_link pnl
on p.parent_id = pnl.parent_id
left outer join nephew n
on n.nephew_id = pnl.nephew_id
where enabled = 1
order by parent_name, n.birthday asc
) where rownum <= 1
【问题讨论】:
-
Donald id = 3引用parent_nephew_link表中的nephew_id = 103 + 104,该表又引用103-->Morty和104-->Ferdie。你能解释一下为什么你想在结果中得到Donald --->Louie而不是Morthy或Ferdie吗?我完全迷失了,我不明白这个逻辑。 -
我的错误-我手动将数据从 sqlfiddle 转录到 stackoverflow 并意外反转了 Donald 和 Mickey。我已经更正了上面显示的数据。谢谢!
标签: oracle left-join outer-join