2013-07-14 17 views
0

我有一個SQL查詢,我想調用從asp.net應用程序中的LINQ到SQL。Linq to SQL |前5個不同的排序按日期

SELECT TOP 5 * 
FROM (SELECT SongId, 
       DateInserted, 
       ROW_NUMBER() 
       OVER(
        PARTITION BY SongId 
        ORDER BY DateInserted DESC) rn 
     FROM DownloadHistory) t 
WHERE t.rn = 1 
ORDER BY DateInserted DESC 

我不知道它是否可能通過linq轉到sql,如果沒有的話請提供任何其他方式。

回答

4

我想你必須將SQL分區更改爲Linq group-by。 (實際上所有的分區確實是按歌曲,然後選擇最新的行爲每個組。)因此,像這樣:

IEnumerable<DownloadHistory> top5Results = DownloadHistory 
    // group by SongId 
    .GroupBy(row => row.SongId) 

    // for each group, select the newest row 
    .Select(grp => 
     grp.OrderByDescending(historyItem => historyItem.DateInserted) 
     .FirstOrDefault() 
    ) 

    // get the newest 5 from the results of the newest-1-per-song partition 
    .OrderByDescending(historyItem => historyItem.DateInserted) 
    .Take(5); 
+0

它只是像魅力一樣工作。我必須說它看到快速結果真是太棒了。帽子給你McGarnagle!在這裏看到真正的工作實現:[msongs.apphb.com](http://msongs.apphb.com) –

0

雖然McGarnagle回答解決了這個問題,但是當我看到這兩個執行計劃查詢,看到linq to sql與原生sql查詢相比真的太慢了​​,真是太神奇了。查看上面linq to sql的生成查詢:

--It took 99% of the two execution 

SELECT TOP (5) [t3].[SongId], [t3].[DateInserted] 
    FROM (
     SELECT [t0].[SongId] 
     FROM [dbo].[DownloadHistory] AS [t0] 
     GROUP BY [t0].[SongId] 
     ) AS [t1] 
    OUTER APPLY (
     SELECT TOP (1) [t2].[SongId], [t2].[DateInserted] 
     FROM [dbo].[DownloadHistory] AS [t2] 
     WHERE [t1].[SongId] = [t2].[SongId] 
     ORDER BY [t2].[DateInserted] DESC 
     ) AS [t3] 
    ORDER BY [t3].[DateInserted] DESC 


--It took 1% of the two execution 
SELECT TOP 5 t.SongId,t.DateInserted 
    FROM (SELECT SongId, 
       DateInserted, 
       ROW_NUMBER() 
       OVER(
        PARTITION BY SongId 
        ORDER BY DateInserted DESC) rn 
     FROM DownloadHistory) t 
    WHERE t.rn = 1 
    ORDER BY DateInserted DESC