2012-02-25 12 views
6

Mam witrynę społecznościową i zmagam się z zapytaniem. Mam tabelę postów, która zawiera wszystkie posty użytkowników, a następnie tabelę post_comments zawierającą wszystkie komentarze do wpisu. Próbuję znaleźć najnowszy komentarz przez post z tabeli post_comments. Tabela post_comments ma następujące kolumny:Pobierz najnowszy rekord MySQL dla Grupy

post_comment_id, post_id, writer_user_id, post_comment_content, datetime

mam pogrupowane wyniki przez post_id tak:

SELECT * FROM post_comments GROUP BY post_id 

To prawie co robi Chcę, ale zawsze zwraca najstarszy komentarz do każdego postu, nie najnowszy. Jak mogę go uzyskać, aby zwrócić najnowszy komentarz do każdego postu?

+0

Odpowiedź z @alexis jest najlepsza ... należy oznaczyć ją jako zaakceptowaną, aby pytanie to nie pojawiło się na liście "brak odpowiedzi". –

Odpowiedz

-3

Posortowano! I tak tak:

SELECT * FROM (
    SELECT * FROM post_comments ORDER BY datetime DESC 
) AS post_comments 
GROUP BY post_id 
16

GROUP ubocznych jest przeznaczony do stosowania z agregacji funkcji, inaczej dowolnie wybiera jeden wiersz dla każdej grupy. Twoje rozwiązanie (powyżej i w samo odpowiedzi) działa, ponieważ wydaje się, że MySQL zachowuje pierwszy rząd każdej grupy, ale nie masz gwarancji, że tak się zawsze stanie.

Możesz uzyskać datę najnowszego komentarza dla każdego post_id w ten sposób.

select post_id, MAX(datetime) as latest from post_comments group by post_id 

Użyj go, aby wybrać ostatni komentarz:

SELECT t1.* FROM post_comments AS t1 
JOIN (
    SELECT post_id, MAX(datetime) AS latest FROM post_comments GROUP BY post_id 
) AS t2 
ON t1.post_id = t2.post_id AND t1.datetime = t2.latest 
+1

To jest poprawny sposób obsługi takich zapytań. –

2

Ponieważ tak wiele pytań przyjść z „Chcę najnowszy wpis ...”, i mieć trochę czasu daty. Jeśli omawiana tabela jest automatycznie zwiększana, a znacznik daty/czasu ZAWSZE pozostaje w korelacji czasu sekwencyjnego ... tj .: użytkownik nie ma możliwości edycji lub zmiany w inny sposób znacznika czasu w rekordzie, aby wprowadzić dzisiejszy wpis z datą 3 tygodnie temu ... tak wielu będzie próbowało zdobyć ostatnią datę i ponownie dołączyć do niezarejestrowanego klucza. Po prostu uzyskaj maksymalny klucz ID dla postu i używaj go ... Miałbym indeks na ID postu i głównym kluczu auto-inkrementacji.

select 
     P2.* 
    from 
     (select post_id, max(post_comment_id) as LastPost 
      from post_comments 
      group by post_id) LastPerPost 
     JOIN post_comments P2 
      on LastPerPost.LastPost = P2.post_comment_id 
+0

To może nie działać w niektórych przypadkach, takich jak replikacja dwumianowa. –

+0

@ypercube, nie będąc zaznajomionym z tym terminem i patrząc na niego, masz rację, a alternatywą "według daty" byłoby lepsze podejście. – DRapp

+0

Nie jestem pewien, czy istnieje szansa, że ​​różne zamówienia mogłyby się zdarzyć z jednym serwerem, jeśli istnieje wiele połączeń wstawiających dane. Prawdopodobnie nie z sygnaturami czasowymi, może tak z datami dostarczonymi przez aplikacje (które mogą nie mieć idealnie zsynchronizowanych zegarów). Tak czy inaczej, twoja odpowiedź jest dobra dla jednego serwera (chociaż prawdopodobnie nie daje 100% dokładnych wyników). Jeśli wydajność ma znaczenie (i nie możemy dodać dodatkowych indeksów w kolumnie datetime), jest to prawdopodobnie najlepsze zapytanie do użycia. –

Powiązane problemy