Sql 使用GROUPBY子句从具有最大值的行中获取另一个值

Sql 使用GROUPBY子句从具有最大值的行中获取另一个值,sql,sql-server,Sql,Sql Server,对不起,这个标题。我有这张桌子: CREATE TABLE people ( Id int IDENTITY(1,1) PRIMARY KEY, name varchar(50) NOT NULL, FatherId int REFERENCES people(Id), MotherId int REFERENCES people(Id), age int NOT NULL ); 您可以使用以下命令填充: insert into people (name

对不起,这个标题。我有这张桌子:

CREATE TABLE people
(
    Id int IDENTITY(1,1) PRIMARY KEY,
    name varchar(50) NOT NULL,
    FatherId int REFERENCES people(Id),
    MotherId int REFERENCES people(Id),
    age int NOT NULL
);
您可以使用以下命令填充:

insert into people (name, age) VALUES ('Jonny', 50 )
insert into people (name, age) VALUES ('Angela', 48 )
insert into people (name, age) VALUES ('Donny', 55 )
insert into people (name, age) VALUES ('Amy', 55 )
insert into people (name, FatherId, MotherId, age) VALUES ('Marcus', 1, 2, 10)
insert into people (name, FatherId, MotherId, age) VALUES ('Beevis', 1, 2, 5)
insert into people (name, FatherId, MotherId, age) VALUES ('Stew', 3, 4, 24)
insert into people (name, FatherId, MotherId, age) VALUES ('Emily', 3, 4, 25)
我的目标 我想知道每一对父母中最大的孩子的年龄和名字

获得年龄非常简单:

SELECT MAX(age) FROM people WHERE FatherId IS NOT NULL GROUP BY FatherId
但是如果我想知道他们的年龄和名字呢

我试过了 但由于父系的匹配,这只给了所有的孩子

由于GROUPBY子句,我似乎无法获取主键(Id)

我想如果这是不可能的,那么可能需要一些表重组来实现它

编辑 下面是我使用
交叉应用

select child.name, child.age
FROM people parents
CROSS APPLY
(
    select top 1 age, name
    from people child
    where child.FatherId = parents.Id
    ORDER BY age DESC
) child

您可以尝试此查询并查看此


下面是您自己尝试的一个简单调整。这样做的一个可能的优点是,它允许领带

select p1.name, p1.age
from people p1 inner join
    (
        select FatherId, max(age) max_age
        from people
        group by FatherId
    ) p2
    on p2.FatherId = p1.FatherId and p2.max_age = p1.age;

你在问题中也提到了“一组父母”。要做到这一点,您还需要分组并在
MotherId上加入,当然,假设这与现实世界相匹配,在现实世界中,孩子们通常只有一个共同的单亲。两个
嵌套的子选择
语句可以与
内部连接组合使用

SELECT p1.age, p2.name
  FROM 
(
SELECT max(age) age
  FROM people 
 WHERE FatherId is not null
 GROUP BY FatherId ) p1
 INNER JOIN
(
SELECT age, name
  FROM people 
 WHERE FatherId is not null ) p2
 ON ( p1.age = p2.age );

age name
--- ------
10  Marcus
25  Emily

这会让父母双方都满意

declare @t TABLE 
(
    Id int IDENTITY(1,1) PRIMARY KEY,
    name varchar(50) NOT NULL,
    FatherId int,
    MotherId int,
    age int NOT NULL
);
insert into @t (name, age) VALUES 
('Jonny', 50 ),
('Angela', 48 ),
('Donny', 55 ),
('Amy', 55 );
insert into @t (name, FatherId, MotherId, age) VALUES 
('Marcus', 1, 2, 10),
('Beevis', 1, 2, 5),
('Stew', 3, 4, 24),
('Emily', 3, 4, 25);

select tt.name, tt.age
     , tt.fatherName, tt.fatherAge
     , tt.motherName, tt.motherAge
from (
select ta.*
     , tf.name as fatherName, tf.age as fatherAge 
     , tm.name as motherName, tm.age as motherAge
     , row_number() over (partition by ta.FatherID, ta.MotherID order by ta.age desc) as rn
from @t ta 
left join @t tf 
  on tf.id = ta.fatherID
left join @t tm 
  on tm.id = ta.motherID 
  ) as tt 
where FatherID is not null 
  and rn = 1

我不知道为什么我没有想到,是的,年龄一定是一样的。选择这个是为了得到最简单的答案。
SELECT p1.age, p2.name
  FROM 
(
SELECT max(age) age
  FROM people 
 WHERE FatherId is not null
 GROUP BY FatherId ) p1
 INNER JOIN
(
SELECT age, name
  FROM people 
 WHERE FatherId is not null ) p2
 ON ( p1.age = p2.age );

age name
--- ------
10  Marcus
25  Emily
declare @t TABLE 
(
    Id int IDENTITY(1,1) PRIMARY KEY,
    name varchar(50) NOT NULL,
    FatherId int,
    MotherId int,
    age int NOT NULL
);
insert into @t (name, age) VALUES 
('Jonny', 50 ),
('Angela', 48 ),
('Donny', 55 ),
('Amy', 55 );
insert into @t (name, FatherId, MotherId, age) VALUES 
('Marcus', 1, 2, 10),
('Beevis', 1, 2, 5),
('Stew', 3, 4, 24),
('Emily', 3, 4, 25);

select tt.name, tt.age
     , tt.fatherName, tt.fatherAge
     , tt.motherName, tt.motherAge
from (
select ta.*
     , tf.name as fatherName, tf.age as fatherAge 
     , tm.name as motherName, tm.age as motherAge
     , row_number() over (partition by ta.FatherID, ta.MotherID order by ta.age desc) as rn
from @t ta 
left join @t tf 
  on tf.id = ta.fatherID
left join @t tm 
  on tm.id = ta.motherID 
  ) as tt 
where FatherID is not null 
  and rn = 1