2012-04-05 17 views
24

moim stole wygląda następująco (i używam MySQL):Korzystanie ORDER BY i GROUP BY razem

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

Moim celem jest, aby każdy m_id jeden raz, a zamówienie przez najwyższą datownik.

Wynik powinien być:

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

i 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 to powoduje, ponieważ najpierw robi GROUP_BY, a następnie ZAMÓW wyniki.

Wszelkie pomysły? Dziękuję Ci.

+2

użycie 'MAX' wybrać max z grupy – Nanne

+6

' klauzula GROUP BY' bez funkcji zagregowanej (np: 'count(), SUM(), MAX()') nie ma sensu w ogóle . Wprawia mnie to w zakłopotanie, że MySQL na to pozwala. Pomyśl o tym, dlaczego grupujesz się, jeśli nie robisz nic z grupami? – NullUserException

+0

Co jeśli istnieją dwa różne v_id dla m_id? Jaki byłby pożądany rezultat? –

Odpowiedz

31

Jednym ze sposobów, aby to zrobić 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żdej odrębnej m_id w podzapytaniu
  • wybiera tylko wiersze z table które pasują do wiersza z podzapytania (ta operacja - gdzie wykonywane jest łączenie, ale nie są wybierane kolumny z drugiej tabeli, jest ona używana tylko jako filtr - jest znana n jako "semijoin" w przypadku, gdy byli ciekawi)
  • porządkuje wiersze
+0

Bardzo dziękuję, że działa świetnie. Czy możesz mi wyjaśnić, co to jest "r"? to jest stolik tymczasowy? jak wywołuje SQL? – Luis

+1

@luis - Wyobraź sobie, że pod-zapytanie jest widokiem; widok w linii. Potrzebuje nazwy, abyś mógł się do niej odwoływać i jej pól. Ta odpowiedź daje widok in-line nazwy "r". Możesz nazwać to prawie cokolwiek chcesz. – MatBailie

+2

@Luis to alias, za pomocą którego możesz odwoływać się do podzapytania. Mógłbym też napisać '(wybierz ...) jako r' (zwróć uwagę na as), aby było bardziej zrozumiałe. –

5

Jeśli naprawdę nie obchodzi, o których timestamp dostaniesz a v_id jest zawsze taka sama dla danego m_i można zrobić następujące:

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

teraz, jeśli v_id zmiany dla danego m_id wówczas 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 
2

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

Można spróbować to

SELECT tbl.* FROM (SELECT * FROM table ORDER BY timestamp DESC) as tbl 
GROUP BY tbl.m_id 
+0

Niezły pomysł. Wybierasz wszystkie wiersze bez ograniczeń. – AliN11

1

Tylko trzeba desc ASC. Napisz zapytanie jak poniżej. Zwróci wartości w porządku rosnącym. SELECT * FROM table GROUP BY m_id ORDER BY m_id asc;

+0

To nie zadziała. Chociaż odwróci wyniki, nadal nie zwróci pożądanych rezultatów. – Richlv

0

Należy zamienić DESC na ASC. Wpisz zapytanie w ten sposób, a następnie zwróci wartości w porządku rosnącym.

SELECT * FROM table GROUP BY m_id ORDER BY m_id ASC;