Używanie ORDER BY i GROUP BY together

Moja tabela wygląda tak (i używam MySQL):

m_id | v_id | timestamp
------------------------
6    |   1  | 1333635317
34   |   1  | 1333635323
34   |   1  | 1333635336
6    |   1  | 1333635343
6    |   1  | 1333635349

Moim celem jest pobranie każdego m_id jeden raz i kolejność według najwyższego znacznika czasu.

Wynik powinien brzmieć:

m_id | v_id | timestamp
------------------------
6    |   1  | 1333635343
34   |   1  | 1333635336

A ja napisałem to zapytanie:

SELECT * FROM table GROUP BY m_id ORDER BY timestamp DESC

Ale wyniki są następujące:

m_id | v_id | timestamp
------------------------
34   |   1  | 1333635323
6    |   1  | 1333635317

Myślę, że powoduje, ponieważ najpierw robi GROUP_BY, a następnie porządkuje wyniki.

Jakieś pomysły? Dziękuję.
Author: Matt Fenwick, 2012-04-05

8 answers

Jeden sposób, aby to zrobić, który poprawnie używa group by:

select l.* 
from table l
inner join (
  select 
    m_id, max(timestamp) as latest 
  from table 
  group by m_id
) r
  on l.timestamp = r.latest and l.m_id = r.m_id
order by timestamp desc

Jak to działa:

  • wybiera najnowszy znacznik czasu dla każdego odrębnego m_id w zapytaniu podrzędnym
  • wybiera tylko wiersze z table, które pasują do wiersza z zapytania podrzędnego (Ta operacja -- gdzie wykonywane jest połączenie, ale żadne kolumny nie są wybierane z drugiej tabeli, jest używana tylko jako filtr -- jest znana jako "semijoin" W przypadku, gdy byłeś ciekawy)
  • porządkuje wiersze
 36
Author: Matt Fenwick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-18 13:02:45

Jeśli naprawdę nie zależy ci na tym, który znacznik czasu otrzymasz I Twój v_id jest zawsze taki sam dla danego m_i, możesz wykonać następujące czynności:

select m_id, v_id, max(timestamp) from table
group by m_id, v_id
order by timestamp desc

Teraz, jeśli v_id zmienia się dla danego m_id to należy wykonać następujące czynności

select t1.* from table t1
left join table t2 on t1.m_id = t2.m_id and t1.timestamp < t2.timestamp
where t2.timestamp is null
order by t1.timestamp desc
 7
Author: Mosty Mostacho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-05 14:55:10

Możesz spróbować tego

 SELECT tbl.* FROM (SELECT * FROM table ORDER BY timestamp DESC) as tbl
 GROUP BY tbl.m_id  
 4
Author: Ronak59,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-11 09:50:17

SQL>

SELECT interview.qtrcode QTR, interview.companyname "Company Name", interview.division Division 
FROM interview 
JOIN jobsdev.employer 
    ON (interview.companyname = employer.companyname AND employer.zipcode like '100%')
GROUP BY interview.qtrcode, interview.companyname, interview.division
ORDER BY interview.qtrcode;
 3
Author: Go ahead,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-01 08:09:41

Po prostu musisz desc z asc. Napisz zapytanie jak poniżej. Zwróci wartości w kolejności rosnącej. SELECT * FROM table GROUP BY M_ID ORDER BY m_id asc;

 1
Author: Gurpreet Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-18 16:22:33

Oto najprostsze rozwiązanie

Select m_id, v_id, max (timestamp) from table group by m_id;

Grupuj według m_id, ale uzyskaj maksymalny znacznik czasu dla każdego m_id.

 1
Author: abinash sahoo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-22 06:01:42

Należy zastąpić DESC przez ASC. Napisz zapytanie w ten sposób, a zwróci ono wartości w kolejności rosnącej.

SELECT * FROM table GROUP BY m_id ORDER BY m_id ASC;
 0
Author: MES -,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-02 04:55:45

Dlaczego to takie skomplikowane? To zadziałało.

SELECT M_ID, v_id, MAX (TIMESTAMP) AS TIME FROM table_name GROUP BY m_id

 -1
Author: Vikas Garhwal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-02 14:04:47