EF Core中Partition by實現

一、SQL語句實現

Partition by是SQL Server數據庫中提供的分區函數,跟Group by不同的是,Partition by能夠按照分區返回所有記錄,而Group by只能返回一條記錄。

舉個例子,有如下的數據庫,需要找出每個唯一編號最新狀態的數據。

顯然,CW048201和CW048202它們的最新狀態都是取消報廢狀態,用Group By去獲取單行數據是無法獲取的。這裏我就可以藉助於Partition By。

SQL語句如下:

select * from (
    select ROW_NUMBER() over (partition by EPC order by Scrapdate desc) as fid,* from [dbo].[hps_BaoFei]
) a  

語句執行結果如下:

可以看出分區函數Partitiion By按照編碼分爲了兩個部分並且每個部分按照時間降序排列,因此我們只需再加一個條件即可獲取每個編碼的最新數據。

SQL語句如下:

select * from (
    select ROW_NUMBER() over (partition by EPC order by Scrapdate desc) as fid,* from [dbo].[hps_BaoFei]
) a where a.fid = 1 

語句執行結果如下:

二、EF Core的實現

直接上代碼,我將其封裝到了Web API裏面,可以直接返回結果。

[HttpGet]
[Route("/api/GetBaofei")]
public List<hps_BaoFei> GetBaofei()
{
    using (BroadswordContext _bc = new BroadswordContext())
    {
        List<hps_BaoFei> list = (from p in _bc.hps_BaoFeis.Select(t => t.EPC).Distinct()
                                 from q in _bc.hps_BaoFeis
                                 .Where(t => t.EPC == p)
                                 .OrderByDescending(t => t.Scrapdate)
                                 .Take(1)
                                 select q).ToList();
        return list;
    }
}

注意其中的核心代碼部分,我們可以Debug看一下其生成的SQL語句。

SELECT [t0].[id], [t0].[EPC], [t0].[Remarks], [t0].[ScrapRole], [t0].[ScrapState], [t0].[Scrapdate], [t0].[Scraptime]
FROM (
    SELECT DISTINCT [h].[EPC]
    FROM [hps_BaoFei] AS [h]
) AS [t]
INNER JOIN (
    SELECT [t1].[id], [t1].[EPC], [t1].[Remarks], [t1].[ScrapRole], [t1].[ScrapState], [t1].[Scrapdate], [t1].[Scraptime]
    FROM (
        SELECT [h0].[id], [h0].[EPC], [h0].[Remarks], [h0].[ScrapRole], [h0].[ScrapState], [h0].[Scrapdate], [h0].[Scraptime], ROW_NUMBER() OVER(PARTITION BY [h0].[EPC] ORDER BY [h0].[Scrapdate] DESC) AS [row]
        FROM [hps_BaoFei] AS [h0]
    ) AS [t1]
    WHERE [t1].[row] <= 1
) AS [t0] ON [t].[EPC] = [t0].[EPC]

執行結果:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章