2011-02-10 17 views
5

Potrzebuję pobrać najnowsze wiersze o unikalnej wartości z mojej tabeli mysql. Prosty układ tabeli to znacznik czasu (teraz()) i kolumna użytkownika. Tabela pobiera nowe dane kilka razy na sekundę i potrzebuję najnowszego wiersza, w którym nazwa użytkownika jest unikatowa.Zapytanie MYSQL: najnowszy datownik + unikalna wartość z ostatnich 30 minut

SELECT MAX(timestamp) as timestamp, username 
    FROM bla 
    WHERE timestamp < (now() - interval 30 minute) 
    GROUP BY username 
    ORDER BY timestamp DESC 

Wydaje się, że ta kwerenda nie zwraca ostatnie wartości, prawdopodobnie dlatego, że grupa robi coś nie chcę ...

+0

Więc w zasadzie chcesz najnowszy wiersz dla każdego użytkownik, który został wstawiony w ciągu ostatnich 30 minut? Należy również pamiętać, że 'timestamp' jest zastrzeżonym słowem w mysql. Powinieneś używać innej nazwy dla pola lub "uciekać" za pomocą odsunięć. –

+0

Tak, masz rację, moja kolumna używa innej nazwy dla wartości znacznika czasu to był tylko przykład :) dzięki za wskazówkę i tak! – HyperDevil

Odpowiedz

2
SELECT MAX(timestamp) as timestamp, username 
    FROM bla 
    WHERE timestamp > (now() - interval 30 minute) 
    GROUP BY username 
    ORDER BY timestamp DESC 
6

Jeśli próbujesz spojrzeć na ostatnie 30 minut, a następnie Myślę, że chcesz użyć słowa "większy niż", a nie "mniej niż".

... WHERE timestamp > (now() - interval 30 minute) ... 
+0

+1 Właśnie chciałem kliknąć Prześlij. Miło - piszesz szybciej. ;-) –

+0

Ups, tak, widziałem to, ale wynik wciąż nie pokazuje ostatnich wartości. – HyperDevil

+0

@HyperDevil: Jeśli wiersze są wstawiane z szybkością 2/sekundę, prawdopodobnie trudno będzie zweryfikować wyniki zapytania dla danych na żywo. –

3

Choć co napisałeś nie praca, szybszy rozwiązaniem może być użycie LEFT JOIN Na DB pracuję na LEFT JOIN jest faktycznie dwa razy szybciej niż w/dodatkowy bonus, który można dostać wszystkie kolumny z ostatnich rzędów jeśli chcesz, aby informacje:

SELECT * 
    FROM `bla` 
    WHERE bla.created_at > (now() - interval 30 minute) AND (next_bla.created_at IS NULL) 
    LEFT JOIN bla next_bla ON bla.username = next_bla.username AND bla.created_at < next_bla.created_at 
    ORDER BY bla.created_at DESC 

ten pasuje do każdego wiersza w bla w/w następnym rzędzie przez datownik w/tej samej nazwy użytkownika i wybiera wiersze, które nie mają obok row (next_bla.created_at IS NULL), czyli są to najnowsze wiersze.

Można również użyć klauzuli LIMIT w celu zwiększenia wydajności.

To jest dobry artykuł, który wyjaśnia, jak GROUP BY robót w sposób szczegółowy i jasny język: http://dev.mysql.com/tech-resources/articles/debunking-group-by-myths.html

Inną podobną odpowiedź przez Andomar - MySQL "Group By" and "Order By"

0

SELECT MAX(timestamp) as timestamp, username 
    FROM bla 
    WHERE timestamp > date_sub(now(), interval 30 minute) 
    GROUP BY username 
    ORDER BY timestamp DESC 
Powiązane problemy