SQL ORDER BY 在 GROUP BY 之前

SQL ORDER BY before GROUP BY

这个问题之前已经被问过和回答过很多次了,但我的情况有点不同。

假设我有这个数据:

------------------------------
| id       | date            |
------------------------------
| 1        | 2016-07-15      |
| 1        | 2016-07-16      |
| 2        | 2016-07-24      |
| 2        | 2016-07-25      |
| 1        | 2016-07-29      |
| 1        | 2016-07-30      |
------------------------------

我想先按 date 列排序,然后按 id 列分组,并为每个 id.[=22= 取 max(date) ]

所以我会得到这个

------------------------------
| id       | max(date)       |
------------------------------
| 1        | 2016-07-16      |
| 2        | 2016-07-25      |
| 1        | 2016-07-30      |
------------------------------

请注意 id=1 出现了两次,因为 id=1 的 "groups" 中的 2 个单独 "groups" 的顺序在它们之间有一组 id=2

我的意思是我希望 group by 函数仅将 order by 子句中相邻的具有相同值的行组合在一起。

我该怎么做?

我认为你应该在这里使用变量。

select id, `date`
from (
    select 
        id, 
        `date`, 
        @rowno := case when @grp = id then @rowno + 1 else 0 end as rowno,
        @grp := id
    from (
        select *
        from yourtable
        order by `date` desc
    ) t1
    cross join (select @grp := null, @rowno = 0) t2
) main
where main.rowno = 0
order by `date`;

内部查询将像这样组织记录,

---------------------------------------------
| id       | date            | rowno | @grp |
---------------------------------------------
| 1        | 2016-07-30      | 0     | 1    |
| 1        | 2016-07-29      | 1     | 1    |
| 2        | 2016-07-25      | 0     | 2    |
| 2        | 2016-07-24      | 1     | 2    |
| 1        | 2016-07-16      | 0     | 1    |
| 1        | 2016-07-15      | 1     | 1    |
---------------------------------------------

然后一个 where 子句 rowno = 0 将得到你想要的。

SQLFiddle Demo