Mysql按日期排序,按结果分组

时间:2017-02-27 06:54:56

标签: mysql group-by

我的表结构如下

id  parent  last_date     sub_type  
----------------------------------
11  9       2017-02-28    1101 
10  9       2016-08-26    1101
8   1       2017-02-20    1101  
12  12      2016-08-31    1102      
14  12      2016-12-20    1102      
9   9       2016-12-31    1101  
13  12      2017-03-23    1102  
2   1       2017-01-25    1101  
1   1       2016-12-31    1101 

我想根据日期(最长的第一个)获取每个sub_type的行。我尝试了以下查询

SELECT * FROM mytable GROUP BY sub_type ORDER BY ISNULL(last_date) DESC, last_date DESC  

结果

id  parent  last_date   sub_type    
--------------------------------
1   1       2016-12-31  1101    
12  12      2016-08-31  1102    

但我希望得到以下结果。

id  parent  last_date   sub_type    
--------------------------------   
13  12      2017-03-23  1102 
11  9       2017-02-28  1101    

请指导我获得以上结果。

修改

last_date可能具有NULL值,该值将优先于日期条目。 Thatswhy我选择了ISNULL DESC订单。

4 个答案:

答案 0 :(得分:1)

这是通过某种聚合在每个组中获取一条记录的典型问题。试试这个:

select
    mytable.*
from mytable
join (
    select max(last_date) as last_date, sub_type from mytable group by sub_type
) t1 on mytable.sub_type = t1.sub_type and mytable.last_date = t1.last_date

请参阅此文How to select the first/least/max row per group in SQL

右边的

相关链接

Retrieving the last record in each group

在sqlfiddle中demo

<强> 编辑:

如果没有2个相同的最后日期和空优先级,那么试试这个:

select
    mytable.*
from mytable
join (
    select 
        max(last_date) as last_date, 
        max(isnull(last_date)) nulled, 
        sub_type 
    from mytable 
    group by sub_type
) t1 on mytable.sub_type = t1.sub_type
and (t1.nulled and mytable.last_date is null or (t1.nulled <> 1 and mytable.last_date = t1.last_date))

在sqlfiddle中也是demo

答案 1 :(得分:1)

您也可以根据sub_type列和last_date列的降序给出行号来执行此操作。

<强>查询

select t1.`id`, t1.`parent`, t1.`last_date`, t1.`sub_type` from 
(
    select `id`, `parent`, `last_date`, `sub_type`, 
    (
        case `sub_type` when @A 
        then @R := @R + 1 
        else @R := 1 and @A := `sub_type` end 
    ) as `rn`
    from `your_table_name` t, 
    (select @R := 0, @A := '') r 
    order by `sub_type`, `last_date` desc 
)t1 
where t1.`rn` = 1;

<强> Sql Fiddle demo

答案 2 :(得分:1)

您可以在WHERE子句中使用ORDER BY和LIMIT 1中的相关子查询来查找您要查找的行的ID。

SELECT * 
FROM mytable t1
WHERE id = (
    SELECT id
    FROM mytable t2
    WHERE t2.sub_type = t1.sub_type
    ORDER BY ISNULL(last_date) DESC, last_date DESC, id DESC
    LIMIT 1
)

演示:http://rextester.com/DSPH11524

注意:sub_type应编入索引。

答案 3 :(得分:0)

您写错了查询。

在where子句

之后指定Where条件

以下查询将给出您的预期结果。

SELECT id,parent,max(last_Date),sub_type FROM mytable   GROUP BY sub_type