Im trying to get the older person in a team, im using the group by and min operators, but it not return me the correct values.
This is my example data:
table persons:
id | name | birthdate | team_id
-----------------------------------------
1 | person1 | 1993-09-29 15:15:15 | 1
2 | person2 | 1994-09-29 15:15:15 | 1
3 | person3 | 1992-09-29 15:15:15 | 2
4 | person4 | 1990-09-29 15:15:15 | 2
im using this query to get the older person by team:
select id, name, min(birthdate) from persons group by team_id
im expected the query return me this data:
id | name | min(birthdate)
----------------------------
1 | person1 | 1993-09-29 15:15:15
4 | person4 | 1990-09-29 15:15:15
but it is returning this:
id | name | min(birthdate)
----------------------------
1 | person1 | 1993-09-29 15:15:15
3 | person3 | 1990-09-29 15:15:15
the birthdate is correctly returned, but the name and id are incorrect.
What is happening here? What is my error?
This works on every mysql Version.
But you didn't specify what should happen if two have the same birthday.
The second result shows you what happens with my query.
CREATE TABLE persons ( `id` INTEGER, `name` VARCHAR(7), `birthdate` datetime, `team_id` INTEGER ); INSERT INTO persons (`id`, `name`, `birthdate`, `team_id`) VALUES ('1', 'person1', '1993-09-29 15:15:15', '1'), ('2', 'person2', '1994-09-29 15:15:15', '1'), ('3', 'person3', '1992-09-29 15:15:15', '2'), ('4', 'person4', '1990-09-29 15:15:15', '2');
\n✓ \n\n✓ \n
SELECT p.`id`, p.`name`, p.`birthdate`# FROM persons p INNER JOIN (select team_id, min(birthdate) minbirth from persons group by team_id) mint ON p.birthdate = mint.minbirth AND p.team_id = mint.team_id ORDER By p.team_id,p.`id`
\nid | name | birthdate \n-: | :------ | :------------------ \n 1 | person1 | 1993-09-29 15:15:15 \n 4 | person4 | 1990-09-29 15:15:15 \n
INSERT INTO persons (`id`, `name`, `birthdate`, `team_id`) VALUES ('5', 'person5', '1993-09-29 15:15:15', '1'), ('6', 'person6', '1990-09-29 15:15:15', '2');
\n✓ \n
SELECT p.`id`, p.`name`, p.`birthdate`# FROM persons p INNER JOIN (select team_id, min(birthdate) minbirth from persons group by team_id) mint ON p.birthdate = mint.minbirth AND p.team_id = mint.team_id ORDER By p.team_id,p.`id`
\nid | name | birthdate \n-: | :------ | :------------------ \n 1 | person1 | 1993-09-29 15:15:15 \n 5 | person5 | 1993-09-29 15:15:15 \n 4 | person4 | 1990-09-29 15:15:15 \n 6 | person6 | 1990-09-29 15:15:15 \n
db<>fiddle here
This is not an aggregation query. It is a filtering query. I recommend a correlated subquery in the WHERE
clause:
select p.* -- you can select only the columns you want
from persons p
where p.birthdate = (select min(p2.birthdate)
from persons p2
where p2.team_id = p.team_id
);
Another very common approach is to use window functions:
select p.*
from (select p.*,
rank() over (partition by team_id order by birthdate) as seqnum
from persons p
) p
where seqnum = 1;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.