2013-02-16 45 views
4

我將如何選擇MySQL中每個組的第一行(按日期時間排序)?如何選擇每個組的第一行(按日期時間排序)?

我嘗試,我得到這樣的:

SELECT * 
FROM `cats` 
WHERE `war_id` = 0 
AND `eyes_color` = 'green' 
AND `id` IN 
    (SELECT `id` FROM 
     (SELECT * FROM `cats` ORDER BY `date_last_fought` DESC) AS t 
    GROUP BY `war_id`, `n_of_medals`) 

它有點兒工作,但我不知道這是否是有史以來最好的。

您認爲我可以簡化嗎?

+1

這實際上似乎是最好的選擇。把它變成同一張桌子上的連接沒有多大意義。然而,你應該把'SELECT \'id \''放在最裏面的查詢中,並且'SELECT *'放在任何包裝查詢中。 – Zenexer 2014-01-27 00:20:04

回答

5

我嘗試simpilify這個......

SELECT * FROM `cats` 
inner join (select * from cats 
     WHERE `warid` = 1 AND `color` = 'green' 
     order by orderDate desc) a 
     on (cats.id=a.id) 
group by cats.warId; 


你可以看到這裏http://sqlfiddle.com/#!2/55f5b/5
,但我不能肯定它比你的更好的查詢,...閱讀EXPLAIN &行爲還是成爲了我的家庭作業:d

ID SELECT_TYPE TABLE  TYPE POSSIBLE_KEYS KEY KEY_LEN REF ROWS EXTRA 
1 PRIMARY  <derived2> ALL  (null)   (null) (null) (null) 2 Using temporary; Using filesort 
1 PRIMARY  cats  eq_ref PRIMARY   PRIMARY 4  a.id  1 
2 DERIVED  cats  ALL  (null)   (null) (null) (null) 6 Using filesort 

,並添加索引將使其更快

+0

是否有任何方法來刪除子查詢,並仍然有一個單一的查詢? – CCC 2013-11-26 18:19:06

+0

@CarlosP沒有任何可靠的方法。有一些技巧,如果你小心,索引幾乎總能工作。 – Brilliand 2014-05-15 21:51:35

+0

你必須使用兩個'*'嗎?該查詢將組合這兩個數據集。在這種情況下,喲只需要在內部連接查詢中獲取id。 – kezi 2015-09-05 15:00:37

0

這裏是我的解決方案:

SELECT * FROM `cats` c 
JOIN (
    SELECT `war_id`, `n_of_medals`, MAX(`date_last_fought`) date_last_fought 
    FROM `cats` 
    WHERE `war_id` = 0 
    AND `eyes_color` = 'green' 
    GROUP BY `war_id`, `n_of_medals` 
) c_summary ON c_summary.war_id = c.war_id 
AND c_summary.n_of_medals = c.n_of_medals 
AND c_summary.date_last_fought = c.date_last_fought 
ORDER BY c.`date_last_fought` DESC; 

http://sqlfiddle.com/#!2/05bcb/2

相關問題