2012-11-04 13 views
7

Ho la seguente interrogazione voglio il fuoco:SQL Query - Combina DISTINCT e TOP?

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

Tuttavia, quando ho fuoco, ottengo l'errore:

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

ho cercato di modificare la query, quindi ha usato GROUP BY invece, ma poi ho il seguente problema:

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. 

cosa voglio:

0.123.

Pensa a questo come a un forum. Ci sono post (dbForumPosts) e voci (dbForumEntry). Ci sono 0-molte voci pr post.

Quello che voglio è ottenere i post con l'attività più recente (post con le ultime voci aggiornate in).

+0

Quale DBMS stai utilizzando? –

+0

SQL Server 2008 R2 (MSSQL) –

+0

Possono esserci più di un 'Datemade' per' PostId'? Se sì quale usare per gli ordini? –

risposta

5

È possibile trovare il più recente Datemade per PostId con row_number. Quindi è possibile cercare le più recenti 5 posti:

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 

In alternativa, è possibile ottenere lo stesso con un group by subquery:

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

Se dbForumEntry ha una colonna ID (ad esempio ForumEntryId), una query come questo potrebbe funzionare meglio. Il database può eseguire ciò senza compilare lo row_number o max(Datemade) per l'intera tabella.

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

Grazie mille - mi ha davvero aiutato :-)! Grazie. –