2012-11-04 39 views
7

Tôi đã truy vấn sau đây tôi muốn cháy:Truy vấn SQL - Kết hợp DISTINCT và TOP?

SELECT DISTINCT TOP(5) fp.PostId FROM dbForumPosts fp 
LEFT JOIN dbForumEntry fe ON fp.PostId = fe.PostId 
Order by fe.Datemade DESC 

Tuy nhiên, khi tôi cháy nó, tôi nhận được lỗi:

Msg 145, Level 15, State 1, Line 1 
ORDER BY items must appear in the select list if SELECT DISTINCT is specified. 

Tôi cố gắng để thay đổi các truy vấn, vì vậy nó được sử dụng GROUP BY thay vào đó, nhưng sau đó tôi có vấn đề sau đây:

Msg 8127, Level 16, State 1, Line 4 
Column "dbForumEntry.Datemade" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause. 

tÔI MUỐN GÌ:

0.123.

Hãy nghĩ đây là một diễn đàn. Có các bài viết (dbForumPosts) và các mục (dbForumEntry). Có 0-nhiều mục pr bài.

Điều tôi muốn là nhận các bài đăng có hoạt động gần đây nhất (các bài đăng có các mục nhập cập nhật mới nhất).

+0

Bạn đang sử dụng DBMS nào? –

+0

SQL Server 2008 R2 (MSSQL) –

+0

Có thể có nhiều hơn một 'Datemade' cho mỗi' PostId' không? Nếu như vậy mà một trong những sử dụng cho mục đích đặt hàng? –

Trả lời

5

Bạn có thể tìm thấy Datemade gần đây nhất trên PostId với row_number. Sau đó, bạn có thể tìm kiếm trong 5 bài viết gần đây nhất:

select top 5 PostId 
from (
     select PostId 
     ,  Datemade 
     ,  row_number() over (partition by PostId 
        order by Datemade) as rn 
     from dbForumEntry 
     ) SubQueryAlias 
where rn = 1 -- Most recent row per PostId 
order by 
     Datemade desc 

Ngoài ra, bạn có thể đạt được cùng với một subquery group by:

select top 5 PostId 
from (
     select PostId 
     ,  max(Datemade) as LastDate 
     from dbForumEntry 
     group by 
       PostId 
     ) SubQueryAlias 
order by 
     LastDate desc 

Nếu dbForumEntry có cột ID (nói ForumEntryId), một truy vấn như thế này có thể hoạt động tốt hơn. Cơ sở dữ liệu có thể chạy điều này mà không cần biên dịch row_number hoặc max(Datemade) cho toàn bộ bảng.

select top 5 PostId 
from dbForumPosts fp 
where not exists -- No later entry for the same post exists 
     (
     select * 
     from dbForumPosts fp2 
     where fp2.PostId = fp.PostId 
       and fp2.ForumEntryId > fp.ForumEntryId 
     ) 
order by 
     Datemade desc 
+0

Cảm ơn rất nhiều - nó thực sự đã giúp :-)! Cảm ơn. –

Các vấn đề liên quan