【问题标题】:DENSE_RANK() using LINQ without intermediary stepsDENSE_RANK() 使用 LINQ,无需中间步骤
【发布时间】:2020-06-21 13:10:27
【问题描述】:

我的 SQL SERVER RANK() 函数通过以下 URL 工作:

https://stackoverflow.com/questions/27469838/is-there-a-function-in-entity-framework-that-translates-to-the-rank-function-i?noredirect=1&lq=1

下面的答案似乎可以完成这项工作:

var customersByCountry = db.Customers
    .GroupBy(c => c.CountryID);
    .Select(g => new { CountryID = g.Key, Count = g.Count() });
var ranks = customersByCountry
    .Select(c => new 
        { 
            c.CountryID, 
            c.Count, 
            RANK = customersByCountry.Count(c2 => c2.Count > c.Count) + 1
        });

我想如果我不能直接获取DENSE_RANK(),我可以观察RANK() 何时发生变化并尝试基于此选择DENSE_RANK()

var denseRankCounter = 0;

Dictionary<int, int> denseRankWithRank = new Dictionary<int, int>();

denseRankWithRank.Add(customersByCountry[0].RANK, ++denseRankCounter);

for (int x = 1; x < customersByCountry.Count; x++)
{
    if (customersByCountry[x] != customersByCountry[x - 1])
    {
        if (!denseRankWithRank.ContainsKey(customersByCountry[x].RANK))
        {
            denseRankWithRank.Add(customersByCountry[x].RANK, ++denseRankCounter);
        }
    }
}

然后将这些结果应用回结果集,

var denseCustomersByCountry = customersByCountry.Select(c => new
                            {
                                DENSE_RANK = denseRankWithRank[c.RANK],
                                CountryID = c.CountryID
                                // ...  ,any other required 
                            }).ToList();

虽然这有点工作,但它似乎超级麻烦。
我想知道是否有没有字典或任何中间步骤的更简单的方法。

【问题讨论】:

    标签: c# sql-server entity-framework linq linq-to-sql


    【解决方案1】:

    这并不太难。
    我使用上述 jdweng 的方法让它工作,所以我将其标记为答案。
    在我的实际数据库结果中,groupBy 真的很慢,所以我创建了一个字段子集,然后进行了实际分组。

    var customers = db.Customers.OrderBy(c=>c.CountryID);
    
        var ranks = customers.Select(c => new 
                                      { 
                                            c.CountryID, 
                                            c.Count, 
                                            RANK = customers.Count(c2 => c2.Count > c.Count) + 1
                                        });
    
    
        var denseCustomersByCountry = ranks.GroupBy(r => r.RANK)
                                                .Select((r, idx) => new
                                                {
                                                    RANK = r.Key,
                                                    COUNT = r.Count(),
                                                    DENSE_RANK = idx + 1,
                                                    CountryID = r.FirstOrDefault().CountryID
                                                })
                                                .ToList();
    

    【讨论】:

    • 你不需要orderby来获得排名吗?否则,你只有一个索引号。
    【解决方案2】:

    尝试以下:

                var customersByCountry = db.Customers
                    .GroupBy(c => c.CountryID)
                    .OrderByDescending(x => x.Count())
                    .Select((g,rank) => new { CountryID = g.Key, Count = g.Count(), Rank = rank });
    

    【讨论】:

    • 谢谢!我使用这种方法让它工作,虽然我不能对我的实际数据库结果进行分组,因为它非常慢。我已将详细信息放在答案中
    猜你喜欢
    • 2017-08-22
    • 1970-01-01
    • 2016-03-05
    • 1970-01-01
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    • 2019-03-23
    • 1970-01-01
    相关资源
    最近更新 更多