简体   繁体   English

在 group by 和 min mysql 中获取错误数据

[英]get bad data in group by and min mysql

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.我试图让年长的人加入团队,我使用 group by 和 min 运算符,但它没有返回正确的值。

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.正确返回了生日,但名称和 ID 不正确。

What is happening here?这里发生了什么? What is my error?我的错误是什么?

This works on every mysql Version.这适用于每个 mysql 版本。

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 | 1 | person1 |个人1 | 1993-09-29 15:15:15 1993-09-29 15:15:15\n 4 | 4 | person4 |人4 | 1990-09-29 15:15:15 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 | 1 | person1 |个人1 | 1993-09-29 15:15:15 1993-09-29 15:15:15\n 5 | 5 | person5 |人5 | 1993-09-29 15:15:15 1993-09-29 15:15:15\n 4 | 4 | person4 |人4 | 1990-09-29 15:15:15 1990-09-29 15:15:15\n 6 | 6 | person6 |人6 | 1990-09-29 15:15:15 1990-09-29 15:15:15\n

db<>fiddle here db<> 在这里小提琴

This is not an aggregation query.这不是聚合查询。 It is a filtering query.这是一个过滤查询。 I recommend a correlated subquery in the WHERE clause:我推荐在WHERE子句中使用相关子查询:

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM