2016-12-06 211 views
2

此问题已被提问和回答多次,但我的情况有点不同。SQL ORDER BY 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列,并采取max(date)每个id

这样id=1出现两次,我会得到这个

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

通知,因为的id=1造成2个独立的“组”,在它们之间的一组id=2顺序。

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

我该怎么做?

+0

什么是最大的时间差使得两者的差异使得放入单个组中的日期? – 1000111

+0

@ 1000111没有“差异限制”。问题是,我只想将'order by'子句中相邻的相同'id'的行组合在一起。 – Malki

+0

您的表中没有任何主键吗? – 1000111

回答

4

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

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

+0

这将返回第一个日期而不是每个ID的最后日期。 –

+0

这似乎很聪明,是否在'main'中没有'ORDER BY'保证的顺序? – mendosi

+0

@P.Salmon我已经测试过它,你也可以在sqlfiddle中运行这个查询,但它看起来很糟糕。 – Blank