我正在嘗試撰寫一個查詢,該查詢僅回傳包含每個名稱的最新日期的那些行。
例如,這個資料:
| 姓名 | 銷售日期 | 更多欄目... |
|---|---|---|
| 鮑勃 | 2021-01-05 | |
| 麥克風 | 2021-01-18 | |
| 蘇珊 | 2021-01-23 | |
| 鮑勃 | 2021-02-04 | |
| 蘇珊 | 2021-02-16 | |
| 麥克風 | 2021-03-02 |
會產生這樣的結果:
| 姓名 | 銷售日期 | 更多欄目... |
|---|---|---|
| 鮑勃 | 2021-02-04 | |
| 蘇珊 | 2021-02-16 | |
| 麥克風 | 2021-03-02 |
它有點像 a GROUP BY,但我沒有聚合任何東西。我只想過濾原始行。
我怎么能寫這樣的查詢?
注意:最后,這將是一個 SQL Server 查詢,但我需要使用物體框架來撰寫它。
更新:實際上,這是一個更復雜的查詢的一部分。將它作為原始 SQL 查詢來實作對我來說非常困難。如果可能的話,我需要使用物體框架來實作。
uj5u.com熱心網友回復:
兩種選擇
Select top 1 with ties *
From YourTable
Order by row_number() over (partition by Name order by Sold_Date desc)
或稍高一點的性能
with cte as (
Select *
,RN = row_number() over (partition by Name order by Sold_Date desc)
From YourTable
)
Select *
From cte
Where RN=1
uj5u.com熱心網友回復:
嘗試這個
;with Groups as
(
Select [Name], max([Date Sold]) as [Date Sold]
From Table
Group By [Name]
)
Select Table.* From Groups
Inner Join Table on Table.[Name] = Groups.Name And Table.[Date Sold] = Groups.[Date Sold]
uj5u.com熱心網友回復:
在 GroupBy() 之后展平 IQueryable<T> 時改編自 Error
var names = _context.Items.Select(row => row.Name).Distinct();
var items =
from name in names
from item in _context.Items
.Where(row => row.Name == name)
.OrderByDescending(row => row.DateSold)
.Take(1)
select item;
var results = items.ToArrayAsync();
讓我們分解一下:
一個查詢運算式,它為我們的下一個查詢建立鍵。最終將作為子查詢運行。
var names = _context.Items.Select(row => row.Name).Distinct();
另一個查詢,從鍵開始......
var items =
from name in names
...對于每個鍵,讓我們找到匹配的行...
from item in _context.Items
.Where(row => row.Name == name)
.OrderByDescending(row => row.DateSold)
.Take(1)
...我們想要那一行。
select item;
運行組合查詢。
var results = items.ToArrayAsync();
uj5u.com熱心網友回復:
如果您必須在沒有計算機的情況下自己完成此操作,您將如何解決此問題?
好吧,您將使用名稱為“Bob”的第一行。您將讀取名稱為“Bob”的所有其他行,并從每一行檢查 DateSold 是否比您已有的新。如果日期較新,則將其替換為當前行。如果不是,請繼續下一個“Bob”行。
當然,您必須對看到的每個名稱執行此操作。
因此,讓我們制作一個完全執行此操作的程式。為了提高效率,我們只列舉您的輸入序列一次。
我會將其作為擴展方法,以便您可以將其用作任何其他 LINQ 方法。如果您不熟悉擴展方法,請考慮閱讀擴展方法揭秘
如果你只需要做這個問題,只為這個類做一個擴展方法。如果您認為要重用您的類,請將其設為通用解決方案。
我不知道您序列中的型別,所以假設它是Sales. 從每個Sale我們看到出售它的人的姓名、出售日期和其他一些列。
僅供銷售:不可重復使用
public static IEnumerable<Sale> GetLatestSales(this IEnumerable<Sale> sales)
{
// TODO: implement
}
用法將是:
IEnumerable<Sale> sales = ...
int currentMonth = DateTime.Today.Month;
var latestSalesThisMonth = sales.Where(sale => sale.DateSold.Month == currentMonth)
.GetLatestSales()
.ToList();
好吧,如果這是您想要的,那就讓我們實施吧!
public static IEnumerable<Sale> GetLatestSales(this IEnumerable<Sale> sales)
{
Dictionary<string, Sale> latestSales = new Dictionary<string, Sale>();
foreach (Sale sale in sales)
{
if (latestSales.TryGetValue(sale.Name, out Sale latestSale))
{
// There is already a Sale for this Name in the dictionary.
// is sale newer than latestSale?
if (sale.DateSold > latestSale.DateSold)
{
// sale is newer, this will be the latestSale for this Name
latestSales[sale.Name] = sale;
}
// else: sale is older than latestSale; do nothing
}
}
return latestSales.Values;
}
通用解決方案:僅保留屬性之一的最大值
輸入引數:
源序列
用作公共值的屬性選擇器(在 Sales 中,這是名稱
用于檢查“最新”的屬性選擇器
一個 EqualityComparer 來比較“名稱”
一個比較器來找到“最新的”
一個 ResultSelector,用于指定回傳值
// TODO: invent a proper name public static IEnumerable<T, TKey, TValue> GetLargest( this IEnumerable source, Func<T, TKey> groupSelector, Func<T, TValue> largestSelector) { return GetLargest(source, groupSelector, largestSelector, null, null, null }
public static IEnumerable<T, TKey, TValue, TResult> GetLargest( this IEnumerable source, Func<T, TKey> groupSelector, Func<T, TValue> largestSelector, Func<T, TResult> resultSelector) { return GetLargest(source, groupSelector, largestSelector, resultSelector, null, null }
public static IEnumerable<T, TKey, TValue, TResult> GetLargest( this IEnumerable source, Func<T, TKey> groupSelector, Func<T, TValue> largestSelector, Func<T, TResult> resultSelector, IEqualityComparer keyComparer, IComparer valueComparer) { // TODO: check input values, e.g. not null etc if (source == null) throw ArgumentNullException(nameof(source)); ...
// resultSelector may be null // if comparer null, use default comparer if (keyComparer == null) keyComparer = EqualityComparer.Default; if (valueComparer == null) valueComparer = Comparer.Default; // code is similar to above: Dictionary<TKey, T> dictionary = new Dictionary<TKey, T>(keyComparer); foreach (T sourceElement in source) { TKey key = keySelector(sourceElement); if (dictionary.TryGetValue(key, out Sale dictionaryElement)) { TValue sourceValue = valueSelector(sourceElement); TValue dictionaryValue = valueSelector(dictionaryElement); if (valueComparer.Compare(sourceValue, dictionaryValue) > 0) { // sourceValue is newer, dictionary[key] = sourceElement; } } } if (resultSelector == null) return dictionary.Values; else return dictionary.Values.Select(dictionaryElement => resultSelecto(dictionaryElement);}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/323654.html
標籤:C# sql-server 实体框架 林克 .net-5
下一篇:行總和不區分大小寫
