2011-01-11 9 views
6

Mam tabelę, która wygląda następująco: comment_id, user_id, comment, last_updated.Jak uzyskać 5 ostatnich komentarzy (zapytanie SQL dla SQL Server) dla każdego użytkownika?

Comment_id to klucz tutaj. Każdy użytkownik może mieć wiele komentarzy.

Jak uzyskać 5 ostatnich komentarzy (zapytanie SQL dla SQL Server) dla każdego użytkownika?

Dane wyjściowe powinny być podobne do oryginalnej tabeli, wystarczy ograniczyć komentarze użytkownika do 5 najnowszych dla każdego użytkownika.

Odpowiedz

10

Zakładając co najmniej SQL Server 2005, dzięki czemu można korzystać z funkcji okna (row_number) i CTE:

;with cteRowNumber as (
    select comment_id, user_id, comment, last_updated, ROW_NUMBER() over (partition by user_id order by last_updated desc) as RowNum 
     from comments 
) 
select comment_id, user_id, comment, last_updated 
    from cteRowNumber 
    where RowNum <= 5 
    order by user_id, last_updated desc 
+0

Dzięki. Myślę, że to działa dobrze. Czy można to zrobić bez ROW_NUMBER(), tylko ze standardową składnią SQL? – myforums

+0

Możesz zastąpić Od cteRowNumber instrukcją select. – JeffO

+2

@myforums: ta ** IS ** standardowa składnia ANSI SQL! –

0
SELECT TOP 5 * FROM table WHERE user_id = x ORDER BY comment_id ASC 

Myślę, że powinienem to zrobić.

+0

To da mi najnowsze komentarze dla 1 użytkownika, prawda? Potrzebuję 5 ostatnich komentarzy dla KAŻDEGO użytkownika. – myforums

+0

"dla każdego użytkownika" prawdopodobnie oznacza, że ​​chce danych dla * wszystkich * użytkowników naraz, nie tylko dla jednego użytkownika. – dkarp

+0

czy nie powróci 5 najstarszych komentarzy (ASC) ** jednego użytkownika **? Nie powinieneś używać sygnatury czasowej DESC? – Nishant

0

W SqlServer 2005 limit ten nie jest prawidłowy.

Zamiast zrobić coś takiego:

SELECT TOP(5) * FROM Comment WHERE user_id = x ORDER BY comment_id ASC 

Zauważ, że ten zakłada, że ​​comment_id jest monotonicznie rośnie, co nie zawsze może być ważne założenie dla pól tożsamości (jeśli muszą być numerację na przykład). Możesz rozważyć alternatywne pole, ale podstawowa struktura będzie taka sama.

Pamiętaj, że jeśli zamawiałeś przez pole daty, chciałbyś posortować je w porządku malejącym, a nie w porządku rosnącym, np.

SELECT TOP(5) * FROM Comment WHERE user_id = x ORDER BY last_updated DESC 
+0

"dla każdego użytkownika" prawdopodobnie oznacza, że ​​chce danych dla * wszystkich * użytkowników naraz, nie tylko dla jednego użytkownika. – dkarp

2

odpowiedź Joe jest najlepszym sposobem, aby to zrobić w SQL Server (przynajmniej ja zakładam, że jest, nie jestem zaznajomiony z CTE). Ale tutaj jest rozwiązanie (niezbyt szybkie!) Przy użyciu standardowego SQL:

SELECT * FROM comments c1 
    WHERE (SELECT COUNT(*) FROM comments c2 
      WHERE c2.user_id = c1.user_id AND c2.last_updated >= c1.updated) <= 5 
+0

Dzięki za to rozwiązanie również. – myforums

Powiązane problemy