SQL:为嵌套的 SELECT 创建全局别名,以便在另一个嵌套的 SELECT 中使用

SQL: create global alias for nested SELECT to be used in another nested SELECT

假设我有一个包含两个表的数据库:people 包含每个人的 ID 和 his/her 出生年份,parents 包含 (parent_id, child_id) 对来表示人与人之间的相对关系。为了使解释更容易,让我们假设每个人有 0 children 或 1 child。这是数据库中数据的示例(作为一组 SQL 在 MySQL 上创建它的语句):

CREATE TABLE people (
    id  INTEGER NOT NULL AUTO_INCREMENT,
    birth_year  INTEGER NOT NULL,
    CONSTRAINT PRIMARY KEY(id)
);

CREATE TABLE parents (
    parent_id   INTEGER NOT NULL,
    child_id    INTEGER NOT NULL,
    CONSTRAINT PRIMARY KEY(parent_id,child_id)
);

-- Not creating FOREIGN KEYS, because it's just an example

INSERT INTO people (id, birth_year) VALUES (1, 1937);
INSERT INTO people (id, birth_year) VALUES (2, 1943);
INSERT INTO people (id, birth_year) VALUES (3, 1974);
INSERT INTO people (id, birth_year) VALUES (4, 2001);
INSERT INTO people (id, birth_year) VALUES (5, 2020);

INSERT INTO parents (parent_id, child_id) VALUES (1, 4);
INSERT INTO parents (parent_id, child_id) VALUES (3, 5);

结果:

现在我想创建一个查询,该查询将检索 id 人的 child 出生在 parent 最早的年龄(例如,如果我是1234年出生的,我的child是1300年出生的,那么我的child出生的年龄是1300 - 1234 = 66,我想找一个child ]比别人早)。

我已经提出了一些查询,但每个查询要么不起作用,要么有重复,或两者兼而有之。我最喜欢的是

SELECT id AS pid, -- Parent id
(SELECT child_id FROM parents WHERE parent_id=pid) AS cid -- Child id
FROM people WHERE
EXISTS(SELECT cid) -- Only selecting parents who have children (not sure this part is correct)
ORDER BY (birth_year - (SELECT birth_year FROM people WHERE id=cid)) ASC -- Order by age when they got their child
LIMIT 1;

但是这个在 MySQL 中失败并出现错误:

ERROR 1054 (42S22) at line 24: Unknown column 'cid' in 'field list'

如何修复错误?我担心的另一件事是,结果,我将 select 不仅是 parent 的 id,还有 his/her children 之一的 id。有可能避免吗? 可能有更好的方法来 select 我正在寻找的数据?

您可以使用连接获取年龄:

select c.*, (p.birth_year - c.birth_year) as parent_age 
from parents pa join
     people p
     on pa.parent_id = p.id join
     people c
     on pa.child_id = pc.id;

要获得最小值的所有行,使用window函数:

select x.*
from (select c.*, (p.birth_year - c.birth_year) as parent_age,
             min(p.birth_year - c.birth_year) over () as min_age
      from parents pa join
           people p
           on pa.parent_id = p.id join
           people c
           on pa.child_id = pc.id
     ) x
where parent_age = min_age;