2012-11-04 24 views
7

Aşağıdaki sorgu Ateşe istiyorum: o GROUP BY kullanılan böyleceSQL Sorgu - DISTINCT ve TOP birleştirin?

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

Ben, sorgu değiştirmeye çalışmış: Ben ateşlendiğinde ortaya

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

Ancak, ben hata alıyorum

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. 

Ben NE İSTİYORSUNUZ:

yerine, ama sonra aşağıdaki sorun var

Bunu bir forum olarak düşünün. Mesajlar (dbForumPosts) ve girdileri (dbForumEntry) vardır. Pr gönderi 0-çok var.

En son etkinliğe sahip yayınları almak (son güncellenen girişleri içeren gönderiler).

+0

Hangi DBMS'yi kullanıyorsunuz? –

+0

SQL Server 2008 R2 (MSSQL) –

+0

PostId başına birden fazla "Datemade" olabilir mi? Öyleyse hangisi sipariş için kullanılacak? –

cevap

5

row_number ile en son Datemade, PostId için bulabilirsiniz. Sonra En son 5 mesajların arayabilirsiniz: Bir Kimlik sütunu (diyelim ForumEntryId) sahiptir

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

dbForumEntry ise, sorgusu:

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 

Alternatif olarak, bir group by alt sorgu ile aynı elde edebilirsiniz Bunun gibi daha iyi performans gösterebilir. Veritabanı, tüm tablo için row_number veya max(Datemade) derlemeden bunu çalıştırabilir.

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

Çok teşekkürler - gerçekten yardımcı oldu :-)! Teşekkürler. –