如何获取某列的第一个和最后一个记录分组?

时间:2015-09-01 14:33:52

标签: 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 byMAX以及MIN函数来获取id,但我不知道如何获取nameage

3 个答案:

答案 0 :(得分:3)

您可以使用以下查询:

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

答案 1 :(得分:1)

这将给出第一个结果:

SELECT id, _id, name, age FROM test
WHERE id IN (SELECT MIN(id) FROM test GROUP BY _id)
   OR id IN (SELECT MAX(id) FROM test GROUP BY _id)

答案 2 :(得分:0)

select minid, maxid, t.id, 
case when t._id = minid then name end as first_name,   
case when t._id = maxid then name end as last_name, 
case when t._id = minid then age end as first_age,   
case when t._id = maxid then age end as last_age
from
(
select min(_id) as minid, max(_id) as maxid, id
from tablename
group by id 
) x
join tablename t on t.id = x.id and t._id = x.minid and t._id = x.maxid
相关问题