2012-07-27 96 views
9

我的表titles的排序是这样的MySQL的日期与GROUP BY

id |group|date    |title 
---+-----+--------------------+-------- 
1 |1 |2012-07-26 18:59:30 | Title 1 
2 |1 |2012-07-26 19:01:20 | Title 2 
3 |2 |2012-07-26 19:18:15 | Title 3 
4 |2 |2012-07-26 20:09:28 | Title 4 
5 |2 |2012-07-26 23:59:52 | Title 5 

我需要按日期降序排序每个小组的最新结果。这样

id |group|date    |title 
---+-----+--------------------+-------- 
5 |2 |2012-07-26 23:59:52 | Title 5 
2 |1 |2012-07-26 19:01:20 | Title 2 

东西,我试过

SELECT * 
FROM `titles` 
GROUP BY `group` 
ORDER BY MAX(`date`) DESC 

但我从歌厅组第一名的成绩。像这样

id |group|date    |title 
---+-----+--------------------+-------- 
3 |2 |2012-07-26 18:59:30 | Title 3 
1 |1 |2012-07-26 19:18:15 | Title 1 

我在做什么错? 如果我使用LEFT JOIN,这个查询会更复杂吗?

+0

如果您只需要两列(例如ID和它的最新时间戳),这可能会工作:http://stackoverflow.com/a/4448536/722036。它比**在具有数百万行的巨大表格上使用子查询更快**。 – 2016-06-26 11:41:20

回答

8

This page对我很有帮助;它教会了我如何使用自连接来获得每个组的最大/最小/行数n行。

在您的情况,它可以应用到影响你想,像这样:

SELECT * FROM 
(SELECT group, MAX(date) AS date FROM titles GROUP BY group) 
AS x JOIN titles USING (group, date); 
0

好吧,如果日期是一组独特的这样的工作(如果没有,你会看到几行是匹配组中的最大日期)。 (此外,列不良命名,“组”,“日期”可能给你的语法错误和这种特殊“组”)

select t1.* from titles t1, (select group, max(date) date from titles group by group) t2 
where t2.date = t1.date 
and t1.group = t2.group 
order by date desc 
0

另一种方法是使用MySQL的用户变量来确定一个“控制中断“在group值。

如果你可以返回一个额外的列活,像这样将工作:

SELECT IF(s.group = @prev_group,0,1) AS latest_in_group 
    , s.id 
    , @prev_group := s.group AS `group` 
    , s.date 
    , s.title 
    FROM (SELECT t.id,t.group,t.date,t.title 
      FROM titles t 
     ORDER BY t.group DESC, t.date DESC, t.id DESC 
     ) s 
    JOIN (SELECT @prev_group := NULL) p 
HAVING latest_in_group = 1 
ORDER BY s.group DESC 

这是什么东西做的是通过group降序排序的所有行和date。 (我们在ORDER BY中的所有列上指定了DESC,以防0127,上有一个索引,MySQL可以对其执行“反向扫描”。包含id列使我们获得了确定性(可重复)行为,有不止一行,最新的date值。)这是内嵌视图别名为s

我们使用的“技巧”是将group值与前一行中的值group进行比较。每当我们有不同的值时,我们知道我们正在启动一个“新”组,并且这一行是“最新”行(我们有IF函数返回1)。否则(当组值匹配时),它不是最新的行(并且我们有IF函数返回0)。

然后,我们筛选出所有没有设置为1的latest_in_group的行。

有可能在另一个查询包裹该查询(如内嵌视图),以去除多余的列:

SELECT r.id 
    , r.group 
    , r.date 
    , r.title 
    FROM (SELECT IF(s.group = @prev_group,0,1) AS latest_in_group 
       , s.id 
       , @prev_group := s.group AS `group` 
       , s.date 
       , s.title 
      FROM (SELECT t.id,t.group,t.date,t.title 
        FROM titles t 
        ORDER BY t.group DESC, t.date DESC, t.id DESC 
       ) s 
      JOIN (SELECT @prev_group := NULL) p 
     HAVING latest_in_group = 1 
     ) r 
ORDER BY r.group DESC 
0

如果您id字段是一个自动递增的字段,它是安全地说,在id场的最高值,也是任何一组的date最高值,那么这是一个简单的解决方案:

SELECT b.* 
FROM  (SELECT MAX(id) AS maxid FROM titles GROUP BY group) a 
JOIN  titles b ON a.maxid = b.id 
ORDER BY b.date DESC 
0

使用下面的MySQL查询,以获得最新更新/插入从表中记录。

SELECT * FROM 
(
    select * from `titles` order by `date` desc 
) as tmp_table 
group by `group` 
order by `date` desc 
1

我通过Google发现此主题,看起来像我有同样的问题。 这是我自己的解决方案,如果像我一样,你不喜欢子查询:

-- Create a temporary table like the output 
CREATE TEMPORARY TABLE titles_tmp LIKE titles; 

-- Add a unique key on where you want to GROUP BY 
ALTER TABLE titles_tmp ADD UNIQUE KEY `group` (`group`); 

-- Read the result into the tmp_table. Duplicates won't be inserted. 
INSERT IGNORE INTO titles_tmp 
    SELECT * 
    FROM `titles` 
    ORDER BY `date` DESC; 

-- Read the temporary table as output 
SELECT * 
    FROM titles_tmp 
    ORDER BY `group`; 

它有一个更好的方式表现。以下是如何提高速度,如果date_column有相同的顺序auto_increment_one(你再不需要一个ORDER BY语句):

-- Create a temporary table like the output 
CREATE TEMPORARY TABLE titles_tmp LIKE titles; 

-- Add a unique key on where you want to GROUP BY 
ALTER TABLE titles_tmp ADD UNIQUE KEY `group` (`group`); 

-- Read the result into the tmp_table, in the natural order. Duplicates will update the temporary table with the freshest information. 
INSERT INTO titles_tmp 
    SELECT * 
    FROM `titles` 

    ON DUPLICATE KEY 
    UPDATE `id` = VALUES(`id`), 
      `date` = VALUES(`date`), 
      `title` = VALUES(`title`); 

-- Read the temporary table as output 
SELECT * 
    FROM titles_tmp 
    ORDER BY `group`; 

结果:

+----+-------+---------------------+---------+ 
| id | group | date    | title | 
+----+-------+---------------------+---------+ 
| 2 |  1 | 2012-07-26 19:01:20 | Title 2 | 
| 5 |  2 | 2012-07-26 23:59:52 | Title 5 | 
+----+-------+---------------------+---------+ 

大表这种方法使在性能方面的重要一点。

0

使用下面的查询,以便从每个组

SELECT 
T1.* FROM 
(SELECT 
    MAX(ID) AS maxID 
FROM 
    T2 
GROUP BY Type) AS aux 
    INNER JOIN 
T2 AS T2 ON T1.ID = aux.maxID ; 

其中ID为您自动递增领域和类型是记录类型,您想组获得最新的记录。

0

MySQL使用的GROUP BY的哑扩展,如果你想因此得到这样的结果是不可靠的,你可以使用

select id, group, date, title from titles as t where id = 
(select id from titles where group = a.group order by date desc limit 1); 

在此查询,每次扫描表已满每组所以可以找到最近的日期。我无法找到任何更好的替代方案。希望这会帮助某人。