mysql - join first and last records by group type?

本小妞迷上赌 提交于 2021-02-10 19:46:43

问题


With a table like:

idx type dat
0   a    foo1
1   b    foo2
2   c    foo3
3   a    foo4
4   b    foo5
5   c    foo6
6   a    foo7
7   b    foo8
8   c    foo9

How can i get the first and last data of each type:

for example:

a foo1 foo7
b foo2 foo8
c foo3 foo9

I have tried this query, but its way to slow, even with indexes on idx and type:

select mins.type, mins.dat, mytable.dat from mytable

--get the maximums
inner join
 (select max(idx) as maxidx from mytable group by type) as a
on a.maxidx = mytable.idx


--join the maximums to the minimums
inner join

--get the minimums
 (select * from mytable inner join (select min(idx) as minidx from mytable group by type) as b 
on b.minidx = mytable.idx ) as mins

on issues.type = mins.type

The join of on issues.type = mins.type seems to be what is slowing it down so much because mins.type is derived and not indexed?


回答1:


Use mysql's "funky" functionality of a GROUP BY without aggregating the other columns, which simply returns the first row of the group. The problem then becomes getting the rows into the correct order before using this functionality, typically by using an aliased query.

This approach avoids any correlated subqueries (queries per row) and needs just two passes over the table (one for each direction of ordering):

select x2.type, x2.dat as first_dat, y2.dat as last_dat
from (select *
  from (select type, dat
    from so8735514
    order by 1, 2) x1
  group by 1) x2
join (select *
  from (select type, dat
    from so8735514
    order by 1, 2 desc) y1
  group by 1) y2 on y2.type = x2.type;

Test code:

create table so8735514 (idx int, type text, dat text);
insert into so8735514 values
(0, 'a', 'foo1'),
(1, 'b', 'foo2'),
(2, 'c', 'foo3'),
(3, 'a', 'foo4'),
(4, 'b', 'foo5'),
(5, 'c', 'foo6'),
(6, 'a', 'foo7'),
(7, 'b', 'foo8'),
(8, 'c', 'foo9');

Output:

+------+-----------+----------+
| type | first_dat | last_dat |
+------+-----------+----------+
| a    | foo1      | foo7     |
| b    | foo2      | foo8     |
| c    | foo3      | foo9     |
+------+-----------+----------+


来源:https://stackoverflow.com/questions/8735514/mysql-join-first-and-last-records-by-group-type

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!