mysql - 如何获取按特定列分组的第一条和最后一条记录?

标签 mysql sql group-by

我有以下 mysql 表:

CREATE TABLE test (id INT, _id INT, name VARCHAR(30), age INT);
INSERT INTO test
(id,  _id,     name,       age) VALUES
(1,     1,  'Lorem',        20),
(2,     1,  'Ipsum',        21),
(3,     1,  'Dolor',        22),
(4,     1,  'Sit',          23),
(5,     1,  'Amet',         24),
(6,     1,  'Consectetur',  25),
(7,     1,  'Adipiscing',   26),
(8,     2,  'Elit',         27),
(9,     2,  'In',           28),
(10,    2,  'Non',          29),
(11,    2,  'Gravida',      30),
(12,    2,  'Erat',         31),
(13,    2,  'Tempor',       32),
(14,    2,  'Augue',        33);

我需要一个查询来根据 _id 获取第一条和最后一条记录。所以最终结果可能是这样的:

| id | _id |    name     | age |
| 1  | 1   | Lorem       | 20  | 
| 7  | 1   | Adipiscing  | 26  |
| 8  | 2   | Elit        | 27  |
| 14 | 2   | Augue       | 33  |

或者这个:

| min_id | max_id | _id | first_name | last_name | first_age | last_age |
|    1   |    7   |  1  | Lorem      | Adipiscing|    20     |    26    |
|    8   |   14   |  2  | Elit       | Augue     |    27     |    33    |

到目前为止,我尝试使用 group byMAXMIN 函数来获取 id,但是我不知道如何获取 nameage

最佳答案

您可以使用以下查询:

SELECT t2.id AS min_id, t3.id AS max_id, t1._id,
       t2.name AS first_name, t3.name AS last_name,
       t2.age AS first_age, t3.age AS last_age
FROM (
   SELECT _id, MIN(age) AS minAge, MAX(age) AS maxAge
   FROM test 
   GROUP BY _id ) AS t1
INNER JOIN test AS t2 ON t2.age = t1.minAge 
INNER JOIN test As t3 ON t3.age = t1.maxAge

这将为您提供第二个结果集。它假设每个 _id 只有一个最小或最大记录。

Demo here

要获取第一个结果集,您可以使用:

SELECT t2.*
FROM (
   SELECT _id, MIN(age) AS minAge, MAX(age) AS maxAge
   FROM test 
   GROUP BY _id ) AS t1
INNER JOIN test AS t2 
   ON t2._id = t1._id AND (t2.age = t1.minAge OR t2.age = t1.maxAge)

Demo here

要处理每个 _id 有多个最小、最大记录的情况,您可以使用:

SELECT MAX(CASE WHEN age = minAge THEN id END) AS min_id,
       MAX(CASE WHEN age = maxAge THEN id END) AS max_id,
       _id,
       MAX(CASE WHEN age = minAge THEN name END) AS first_name,
       MAX(CASE WHEN age = maxAge THEN name END) AS last_name,
       MAX(CASE WHEN age = minAge THEN age END) AS first_age,
       MAX(CASE WHEN age = maxAge THEN age END) AS last_age
FROM (
SELECT GROUP_CONCAT(t1.id) AS id, t1._id, 
       GROUP_CONCAT(t1.name) AS name, t1.age, 
       (SELECT MIN(age) 
        FROM test AS t2
        WHERE t2._id = t1._id) AS minAge, 
       (SELECT MAX(age) 
        FROM test AS t2
        WHERE t2._id = t1._id) AS maxAge        
FROM test AS t1
GROUP BY _id, age ) AS t3
GROUP BY _id

Demo here

关于mysql - 如何获取按特定列分组的第一条和最后一条记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32334383/

相关文章:

php - 如何在MySQL中提取带有 '1'的列

mysql - HIVE 或 SQL 查询用于比较相同样本量的售前和售后

mysql - 网站的两个用户之间的对话类型收件箱消息

mysql - only_full_group_by 不让我按我的意愿显示表格

mysql - 将多行中的日期聚合为一行

python - Pandas groupby - 对用户进行分组并计算订阅类型

PHP - 计算多少天前

php - 如何使用 Laravel 和 Eloquent 查询具有多种关系的数据透视表

PHP数据库从数据库中查询外键数据

java - 如何更改字符串的格式/模式?