получить неверные данные в группе и мин mysql - PullRequest
0 голосов
/ 23 февраля 2020

Я пытаюсь получить пожилого человека в команде, я использую операторы group by и min, но он не возвращает мне правильные значения.

Это мой пример данных:

Таблица лиц:

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

я использую этот запрос, чтобы получить пожилого человека по команде:

select id, name, min(birthdate) from persons group by team_id

я ожидал, что запрос вернет мне эти данные:

id   |  name   |  min(birthdate)  
----------------------------
1    | person1 |  1993-09-29 15:15:15
4    | person4 |  1990-09-29 15:15:15

но он возвращает это:

id   |  name   |  min(birthdate)
----------------------------
1    | person1 |  1993-09-29 15:15:15
3    | person3 |  1990-09-29 15:15:15

дата рождения верна правильно, но имя и идентификатор неверны.

Что здесь происходит? В чем моя ошибка?

Ответы [ 2 ]

1 голос
/ 23 февраля 2020

Это работает на каждой mysql версии.

Но вы не указали, что должно произойти, если у двух одинаковый день рождения.

Второй результат показывает вам, что происходит с моим запросом .

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');
✓

✓
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`
id | name    | birthdate          
-: | :------ | :------------------
 1 | person1 | 1993-09-29 15:15:15
 4 | person4 | 1990-09-29 15:15:15
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');
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`
id | name    | birthdate          
-: | :------ | :------------------
 1 | person1 | 1993-09-29 15:15:15
 5 | person5 | 1993-09-29 15:15:15
 4 | person4 | 1990-09-29 15:15:15
 6 | person6 | 1990-09-29 15:15:15

дБ <> скрипка здесь

0 голосов
/ 23 февраля 2020

Это не запрос агрегации. Это фильтрующий запрос. Я рекомендую коррелированный подзапрос в предложении 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
                    );

Другой очень распространенный подход - использование оконных функций:

select p.*
from (select p.*,
             rank() over (partition by team_id order by birthdate) as seqnum
      from persons p
     ) p
where seqnum = 1;
...