简体   繁体   English

使用 linq 查找第二个最高工资

[英]Find 2nd max salary using linq

I have following sql query for finding 2nd max salary.我有以下 sql 查询来查找第二个最高工资。

Select * From Employee E1 Where
    (2) = (Select Count(Distinct(E2.Salary)) From Employee E2 Where
        E2.Salary > E1.Salary)

I want to convert it into Linq statement.我想把它转换成 Linq 语句。

I think what you're asking is to find the employee with the second-highest salary?我想你要问的是找到薪水第二高的员工?

If so, that would be something like如果是这样,那将类似于

var employee = Employees
    .OrderByDescending(e => e.Salary)
    .Skip(1)
    .First();

If multiple employees may have equal salary and you wish to return an IEnumerable of all the employees with the second-highest salary you could do:如果多个员工可能有相同的薪水,并且您希望返回薪水第二高的所有员工的 IEnumerable,您可以这样做:

var employees = Employees
    .GroupBy(e => e.Salary)
    .OrderByDescending(g => g.Key)
    .Skip(1)
    .First();

(kudos to @diceguyd30 for suggesting this latter enhancement) (感谢@diceguyd30 提出了后一种增强功能)

You can define equally comparer class as bellow:您可以定义同样的比较器类,如下所示:

    public class EqualityComparer : IEqualityComparer<Employee >
    {
        #region IEqualityComparer<Employee> Members
        bool IEqualityComparer<Employee>.Equals(Employee x, Employee y)
        {
            // Check whether the compared objects reference the same data.
            if (Object.ReferenceEquals(x, y))
                return true;

            // Check whether any of the compared objects is null.
            if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
                return false;

            return x.Salary == y.Salary;
        }

        int IEqualityComparer<Employee>.GetHashCode(Employee obj)
        {
            return obj.Salary.GetHashCode();
        }
        #endregion
    }

and use it as bellow:并使用它如下:

    var outval = lst.OrderByDescending(p => p.Id)
                  .Distinct(new EqualityComparer()).Skip(1).First();

or do it without equally comparer (in two line):或者在没有相等比较器的情况下进行(在两行中):

        var lst2 = lst.OrderByDescending(p => p.Id).Skip(1);
        var result = lst2.SkipWhile(p => p.Salary == lst2.First().Salary).First();

Edit: As Ani said to work with sql should do : var lst = myDataContext.Employees.AsEnumerable();编辑:正如 Ani 所说,使用 sql 应该这样做: var lst = myDataContext.Employees.AsEnumerable(); but if is for commercial software it's better to use TSQL or find another linq way.但如果是用于商业软件,最好使用 TSQL 或找到另一种 linq 方式。

List<Employee> employees = new List<Employee>()
{
    new Employee { Id = 1, UserName = "Anil" , Salary = 5000},
    new Employee { Id = 2, UserName = "Sunil" , Salary = 6000},
    new Employee { Id = 3, UserName = "Lokesh" , Salary = 5500},
    new Employee { Id = 4, UserName = "Vinay" , Salary = 7000}
};

var emp = employees.OrderByDescending(x => x.Salary).Skip(1).FirstOrDefault();

Using LINQ , you can find the 3rd highest salary like this:使用LINQ ,您可以像这样找到第三高的薪水:

// first use LINQ to sort by salary, then skip first 2 and get next
var thirdHighestSalary= (from n in db.Employee order by n.salary descending select n).distinct().skip(2).  FirstOrDefault()
// write the result to console
Console.WriteLine(Third Highest Salary is : {0},thirdHighestSalary.Salary);

这将适用于重复记录以及第 n 个最高薪水,只需要与 take 一起玩,然后跳过这一切,例如下面是第三个最高薪水,重复记录存在于表中-

emplist.OrderByDescending(x => x.Salary).Select(x=>x.Salary).Distinct().Take(3).Skip(2).First();
public class Program
{
    public static void Main()
    {
        IList<int> intList = new List<int>() { 10, 21, 91, 30, 91, 45, 51, 87, 87 };

        var largest = intList.Max();

        Console.WriteLine("Largest Element: {0}", largest);

        var secondLargest = intList.Max(i => {
            if(i != largest)
                return i;
            return 0;
        });

        Console.WriteLine("second highest element in list: {0}", secondLargest);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM