一、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]
執行結果: