SQL JOIN return 仅第一场比赛
SQL JOIN return only the first match
我觉得这是一道基础题,但是我想不通。我是新手所以请多多包涵。
我正在分析来自 FIFA 比赛的球员数据,我想得到一个 table 每个球员的最高评分和发生这种情况的最早年龄。
这是数据示例:
id
name
position
rating
age
1
James
RW
70
20
1
James
RW
71
21
2
Frank
CB
73
23
2
Frank
CB
73
24
3
Miles
CM
75
27
3
Miles
CM
74
28
这是查询应该return:
id
name
position
rating
age
1
James
RW
71
21
2
Frank
CB
73
23
3
Miles
CM
75
27
我想我可以先得到每个球员的最高总分,然后 JOIN
得到年龄,但这给了其他年份一个球员有相同的最高评价。
id
name
position
rating
age
1
James
RW
71
21
2
Frank
CB
73
23
2
Frank
CB
73
24
3
Miles
CM
75
27
谢谢,
试试这个(可能会快一点):
with mytable as (
select 1 as id, "James" as name, "RW" as position, 70 as rating, 20 as age union all
select 1, "James", "RW", 71, 21 union all
select 2, "Frank", "CB", 73, 23 union all
select 2, "Frank", "CB", 73, 24 union all
select 3, "Miles", "CM", 75, 27 union all
select 3, "Miles", "CM", 74, 28
)
select array_agg(t order by rating desc, age asc limit 1)[OFFSET(0)].*,
from mytable as t
group by t.id
一种方法使用 ROW_NUMBER
和 QUALIFY
:
SELECT *
FROM yourTable
WHERE true
QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY rating DESC, age) = 1;
如果你愿意,也试试这个。我想这就是你需要的。
select p1.id,
p1.name,
p1.pos,
max(p1.rating),
p1.age
from players p1
join (select name, min(age) min_age
from players
group by 1) p2 on p1.name = p2.name and p1.age = p2.min_age
group by p1.id, p1.name, p1.pos, p1.age
我觉得这是一道基础题,但是我想不通。我是新手所以请多多包涵。
我正在分析来自 FIFA 比赛的球员数据,我想得到一个 table 每个球员的最高评分和发生这种情况的最早年龄。
这是数据示例:
id | name | position | rating | age |
---|---|---|---|---|
1 | James | RW | 70 | 20 |
1 | James | RW | 71 | 21 |
2 | Frank | CB | 73 | 23 |
2 | Frank | CB | 73 | 24 |
3 | Miles | CM | 75 | 27 |
3 | Miles | CM | 74 | 28 |
这是查询应该return:
id | name | position | rating | age |
---|---|---|---|---|
1 | James | RW | 71 | 21 |
2 | Frank | CB | 73 | 23 |
3 | Miles | CM | 75 | 27 |
我想我可以先得到每个球员的最高总分,然后 JOIN
得到年龄,但这给了其他年份一个球员有相同的最高评价。
id | name | position | rating | age |
---|---|---|---|---|
1 | James | RW | 71 | 21 |
2 | Frank | CB | 73 | 23 |
2 | Frank | CB | 73 | 24 |
3 | Miles | CM | 75 | 27 |
谢谢,
试试这个(可能会快一点):
with mytable as (
select 1 as id, "James" as name, "RW" as position, 70 as rating, 20 as age union all
select 1, "James", "RW", 71, 21 union all
select 2, "Frank", "CB", 73, 23 union all
select 2, "Frank", "CB", 73, 24 union all
select 3, "Miles", "CM", 75, 27 union all
select 3, "Miles", "CM", 74, 28
)
select array_agg(t order by rating desc, age asc limit 1)[OFFSET(0)].*,
from mytable as t
group by t.id
一种方法使用 ROW_NUMBER
和 QUALIFY
:
SELECT *
FROM yourTable
WHERE true
QUALIFY ROW_NUMBER() OVER (PARTITION BY id ORDER BY rating DESC, age) = 1;
如果你愿意,也试试这个。我想这就是你需要的。
select p1.id,
p1.name,
p1.pos,
max(p1.rating),
p1.age
from players p1
join (select name, min(age) min_age
from players
group by 1) p2 on p1.name = p2.name and p1.age = p2.min_age
group by p1.id, p1.name, p1.pos, p1.age