2012-07-27 118 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); 

在此查詢,每次掃描表已滿每組所以可以找到最近的日期。我無法找到任何更好的替代方案。希望這會幫助某人。